Initial version of Java editor
Signed-off-by: Ansgar Radermacher <ansgar.radermacher@cea.fr>
Change-Id: I125788978bdb99ea3d0baf8de9a2667b2626b451
diff --git a/plugins/languages/java/org.eclipse.papyrus.designer.languages.java.jdt.texteditor/.classpath b/plugins/languages/java/org.eclipse.papyrus.designer.languages.java.jdt.texteditor/.classpath
new file mode 100644
index 0000000..1db08c6
--- /dev/null
+++ b/plugins/languages/java/org.eclipse.papyrus.designer.languages.java.jdt.texteditor/.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-11"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="target/classes"/>
+</classpath>
diff --git a/plugins/languages/java/org.eclipse.papyrus.designer.languages.java.jdt.texteditor/.project b/plugins/languages/java/org.eclipse.papyrus.designer.languages.java.jdt.texteditor/.project
new file mode 100644
index 0000000..ab7291a
--- /dev/null
+++ b/plugins/languages/java/org.eclipse.papyrus.designer.languages.java.jdt.texteditor/.project
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.papyrus.designer.languages.java.jdt.texteditor</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.m2e.core.maven2Builder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.m2e.core.maven2Nature</nature>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/plugins/languages/java/org.eclipse.papyrus.designer.languages.java.jdt.texteditor/.settings/org.eclipse.core.resources.prefs b/plugins/languages/java/org.eclipse.papyrus.designer.languages.java.jdt.texteditor/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 0000000..99f26c0
--- /dev/null
+++ b/plugins/languages/java/org.eclipse.papyrus.designer.languages.java.jdt.texteditor/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+encoding/<project>=UTF-8
diff --git a/plugins/languages/java/org.eclipse.papyrus.designer.languages.java.jdt.texteditor/.settings/org.eclipse.jdt.core.prefs b/plugins/languages/java/org.eclipse.papyrus.designer.languages.java.jdt.texteditor/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..f4d933e
--- /dev/null
+++ b/plugins/languages/java/org.eclipse.papyrus.designer.languages.java.jdt.texteditor/.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=11
+org.eclipse.jdt.core.compiler.compliance=11
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=11
diff --git a/plugins/languages/java/org.eclipse.papyrus.designer.languages.java.jdt.texteditor/.settings/org.eclipse.m2e.core.prefs b/plugins/languages/java/org.eclipse.papyrus.designer.languages.java.jdt.texteditor/.settings/org.eclipse.m2e.core.prefs
new file mode 100644
index 0000000..f897a7f
--- /dev/null
+++ b/plugins/languages/java/org.eclipse.papyrus.designer.languages.java.jdt.texteditor/.settings/org.eclipse.m2e.core.prefs
@@ -0,0 +1,4 @@
+activeProfiles=
+eclipse.preferences.version=1
+resolveWorkspaceProjects=true
+version=1
diff --git a/plugins/languages/java/org.eclipse.papyrus.designer.languages.java.jdt.texteditor/META-INF/MANIFEST.MF b/plugins/languages/java/org.eclipse.papyrus.designer.languages.java.jdt.texteditor/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..d17dd3a
--- /dev/null
+++ b/plugins/languages/java/org.eclipse.papyrus.designer.languages.java.jdt.texteditor/META-INF/MANIFEST.MF
@@ -0,0 +1,40 @@
+Manifest-Version: 1.0
+Require-Bundle: org.eclipse.ui,
+ org.eclipse.core.runtime,
+ org.eclipse.ui.editors;bundle-version="3.7.0",
+ org.eclipse.uml2.uml;bundle-version="3.2.0",
+ org.eclipse.papyrus.infra.core.log;bundle-version="[1.2.0,3.0.0)",
+ org.eclipse.papyrus.designer.languages.java.profile;bundle-version="1.1.0",
+ org.eclipse.papyrus.uml.tools;bundle-version="[4.3.0,6.0.0)",
+ org.eclipse.papyrus.uml.tools.utils;bundle-version="[3.4.0,5.0.0)",
+ org.eclipse.papyrus.uml.diagram.common;bundle-version="[3.4.0,5.0.0)",
+ org.eclipse.papyrus.designer.languages.common.extensionpoints;bundle-version="1.1.0",
+ org.eclipse.papyrus.designer.languages.java.codegen;bundle-version="1.1.0",
+ org.eclipse.papyrus.designer.transformation.base;bundle-version="0.8.0",
+ org.eclipse.papyrus.designer.languages.common.base;bundle-version="1.1.0",
+ org.eclipse.papyrus.designer.languages.common.codegen.ui;bundle-version="1.1.0",
+ org.eclipse.papyrus.infra.ui,
+ org.eclipse.jface.text;bundle-version="3.0.0",
+ org.eclipse.ui.ide;bundle-version="3.0.0",
+ org.eclipse.papyrus.infra.core;bundle-version="[3.1.0,5.0.0)",
+ org.eclipse.emf.workspace;bundle-version="1.5.0",
+ org.eclipse.papyrus.infra.emf.gmf;bundle-version="[1.3.0,3.0.0)",
+ org.eclipse.jdt;bundle-version="[3.0.0,4.0.0)",
+ org.eclipse.jdt.core;bundle-version="[3.0.0,4.0.0)",
+ org.eclipse.jdt.ui;bundle-version="3.0.0"
+Bundle-Vendor: %providerName
+Bundle-ActivationPolicy: lazy
+Bundle-Version: 1.1.1.qualifier
+Bundle-Localization: plugin
+Bundle-Name: %pluginName
+Bundle-Activator: org.eclipse.papyrus.designer.languages.java.jdt.texteditor.Activator
+Bundle-ManifestVersion: 2
+Bundle-Description: %pluginDescription
+Bundle-SymbolicName: org.eclipse.papyrus.designer.languages.java.jdt.texteditor;singleton:=true
+Bundle-RequiredExecutionEnvironment: JavaSE-11
+Export-Package: org.eclipse.papyrus.designer.languages.java.jdt.texteditor,
+ org.eclipse.papyrus.designer.languages.java.jdt.texteditor.editor,
+ org.eclipse.papyrus.designer.languages.java.jdt.texteditor.handler,
+ org.eclipse.papyrus.designer.languages.java.jdt.texteditor.listener,
+ org.eclipse.papyrus.designer.languages.java.jdt.texteditor.sync
+Automatic-Module-Name: org.eclipse.papyrus.designer.languages.java.jdt.texteditor
diff --git a/plugins/languages/java/org.eclipse.papyrus.designer.languages.java.jdt.texteditor/build.properties b/plugins/languages/java/org.eclipse.papyrus.designer.languages.java.jdt.texteditor/build.properties
new file mode 100644
index 0000000..883d0e1
--- /dev/null
+++ b/plugins/languages/java/org.eclipse.papyrus.designer.languages.java.jdt.texteditor/build.properties
@@ -0,0 +1,8 @@
+source.. = src/
+output.. = target/classes/
+bin.includes = META-INF/,\
+ .,\
+ plugin.xml,\
+ build.properties,\
+ icons/,\
+ plugin.properties
diff --git a/plugins/languages/java/org.eclipse.papyrus.designer.languages.java.jdt.texteditor/icons/obj16/c_file_obj.gif b/plugins/languages/java/org.eclipse.papyrus.designer.languages.java.jdt.texteditor/icons/obj16/c_file_obj.gif
new file mode 100644
index 0000000..0d1a289
--- /dev/null
+++ b/plugins/languages/java/org.eclipse.papyrus.designer.languages.java.jdt.texteditor/icons/obj16/c_file_obj.gif
Binary files differ
diff --git a/plugins/languages/java/org.eclipse.papyrus.designer.languages.java.jdt.texteditor/icons/texteditor.gif b/plugins/languages/java/org.eclipse.papyrus.designer.languages.java.jdt.texteditor/icons/texteditor.gif
new file mode 100644
index 0000000..0d1a289
--- /dev/null
+++ b/plugins/languages/java/org.eclipse.papyrus.designer.languages.java.jdt.texteditor/icons/texteditor.gif
Binary files differ
diff --git a/plugins/languages/java/org.eclipse.papyrus.designer.languages.java.jdt.texteditor/icons/texteditor.xcf b/plugins/languages/java/org.eclipse.papyrus.designer.languages.java.jdt.texteditor/icons/texteditor.xcf
new file mode 100644
index 0000000..1749c42
--- /dev/null
+++ b/plugins/languages/java/org.eclipse.papyrus.designer.languages.java.jdt.texteditor/icons/texteditor.xcf
Binary files differ
diff --git a/plugins/languages/java/org.eclipse.papyrus.designer.languages.java.jdt.texteditor/plugin.properties b/plugins/languages/java/org.eclipse.papyrus.designer.languages.java.jdt.texteditor/plugin.properties
new file mode 100644
index 0000000..85fb75b
--- /dev/null
+++ b/plugins/languages/java/org.eclipse.papyrus.designer.languages.java.jdt.texteditor/plugin.properties
@@ -0,0 +1,12 @@
+# Copyright (c) CEA LIST.
+#
+# This program and the accompanying materials are made
+# available under the terms of the Eclipse Public License 2.0
+# which is available at https://www.eclipse.org/legal/epl-2.0/
+#
+# SPDX-License-Identifier: EPL-2.0
+#
+pluginName=Papyrus CDT editor integration
+providerName=Eclipse Modeling Project
+
+pluginDescription=This plugin provides a editor for uml.Comment. The informations are stored in the .notation
diff --git a/plugins/languages/java/org.eclipse.papyrus.designer.languages.java.jdt.texteditor/plugin.xml b/plugins/languages/java/org.eclipse.papyrus.designer.languages.java.jdt.texteditor/plugin.xml
new file mode 100644
index 0000000..7ce5014
--- /dev/null
+++ b/plugins/languages/java/org.eclipse.papyrus.designer.languages.java.jdt.texteditor/plugin.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+ <extension point="org.eclipse.ui.commands">
+ <command
+ description="Open a JDT Editor"
+ defaultHandler="org.eclipse.papyrus.designer.languages.java.jdt.texteditor.handler.SyncJDTEditorHandler"
+ id="org.eclipse.papyrus.designer.languages.exteditor.jdt.openeditor"
+ name="Open a JDT Editor">
+ </command>
+ </extension>
+ <extension
+ id="org.eclipse.jdt.ui.synceditor"
+ point="org.eclipse.ui.editors">
+ <editor
+ default="true"
+ name="Papyrus synchronizing Java editor"
+ icon="icons/texteditor.gif"
+ class="org.eclipse.papyrus.designer.languages.java.jdt.texteditor.editor.SyncJDTEditor"
+ contributorClass="org.eclipse.jdt.internal.ui.javaeditor.ClassFileEditorActionContributor"
+ symbolicFontName="org.eclipse.jdt.ui.editors.textfont"
+ id="org.eclipse.papyrus.designer.languages.java.jdt.texteditor.editor.SyncJDTEditor">
+ </editor>
+ </extension>
+
+ <extension point="org.eclipse.ui.menus">
+ <menuContribution
+ allPopups="false"
+ locationURI="popup:org.eclipse.papyrus.designer.popup?after=codegen">
+ <command
+ commandId="org.eclipse.papyrus.designer.languages.exteditor.jdt.openeditor"
+ id="org.eclipse.papyrus.designer.languages.exteditor.jdt.open"
+ icon="icons/texteditor.gif"
+ style="push">
+ <visibleWhen checkEnabled="true"/>
+ <iterate>
+ <adapt type="org.eclipse.emf.ecore.EObject">
+ <or>
+ <instanceof value="org.eclipse.uml2.uml.Class"/>
+ <instanceof value="org.eclipse.uml2.uml.Operation"/>
+ <instanceof value="org.eclipse.uml2.uml.Transition"/>
+ </or>
+ </adapt>
+ </iterate>
+ </command>
+ </menuContribution>
+ </extension>
+ <extension point="org.eclipse.papyrus.infra.core.modelListener">
+ <listener
+ name="org.eclipse.papyrus.designer.languages.exteditor.jdt.listener.ModelListener"
+ realization="org.eclipse.papyrus.designer.languages.java.jdt.texteditor.listener.ModelListener">
+ </listener>
+ </extension>
+</plugin>
diff --git a/plugins/languages/java/org.eclipse.papyrus.designer.languages.java.jdt.texteditor/pom.xml b/plugins/languages/java/org.eclipse.papyrus.designer.languages.java.jdt.texteditor/pom.xml
new file mode 100644
index 0000000..0d1035a
--- /dev/null
+++ b/plugins/languages/java/org.eclipse.papyrus.designer.languages.java.jdt.texteditor/pom.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.eclipse.papyrus.designer</groupId>
+ <artifactId>org.eclipse.papyrus.designer.languages.java</artifactId>
+ <version>1.1.1-SNAPSHOT</version>
+ </parent>
+ <artifactId>org.eclipse.papyrus.designer.languages.java.jdt.texteditor</artifactId>
+ <packaging>eclipse-plugin</packaging>
+ <description>This module contains the Papyrus CDT integration for C++ (definition for model-explorer)</description>
+</project>
diff --git a/plugins/languages/java/org.eclipse.papyrus.designer.languages.java.jdt.texteditor/src/org/eclipse/papyrus/designer/languages/java/jdt/texteditor/Activator.java b/plugins/languages/java/org.eclipse.papyrus.designer.languages.java.jdt.texteditor/src/org/eclipse/papyrus/designer/languages/java/jdt/texteditor/Activator.java
new file mode 100644
index 0000000..fa4554b
--- /dev/null
+++ b/plugins/languages/java/org.eclipse.papyrus.designer.languages.java.jdt.texteditor/src/org/eclipse/papyrus/designer/languages/java/jdt/texteditor/Activator.java
@@ -0,0 +1,73 @@
+/*****************************************************************************
+ * Copyright (c) 2012 CEA LIST.
+ *
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Vincent Lorenzo (CEA LIST) Vincent.Lorenzo@cea.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.designer.languages.java.jdt.texteditor;
+
+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 Activator extends AbstractUIPlugin {
+
+ // The plug-in ID
+ public static final String PLUGIN_ID = "org.eclipse.papyrus.designer.languages.java.jdt.texteditor"; //$NON-NLS-1$
+
+ // The shared instance
+ private static Activator plugin;
+
+ public static LogHelper log;
+
+ /**
+ * The constructor
+ */
+ public Activator() {
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
+ */
+ @Override
+ public void start(BundleContext context) throws Exception {
+ super.start(context);
+ plugin = this;
+ log = new LogHelper(this);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
+ */
+ @Override
+ public void stop(BundleContext context) throws Exception {
+ plugin = null;
+ super.stop(context);
+ }
+
+ /**
+ * Returns the shared instance
+ *
+ * @return the shared instance
+ */
+ public static Activator getDefault() {
+ return plugin;
+ }
+
+}
diff --git a/plugins/languages/java/org.eclipse.papyrus.designer.languages.java.jdt.texteditor/src/org/eclipse/papyrus/designer/languages/java/jdt/texteditor/AddProfileAndModelLibsHandler.java b/plugins/languages/java/org.eclipse.papyrus.designer.languages.java.jdt.texteditor/src/org/eclipse/papyrus/designer/languages/java/jdt/texteditor/AddProfileAndModelLibsHandler.java
new file mode 100644
index 0000000..d19d179
--- /dev/null
+++ b/plugins/languages/java/org.eclipse.papyrus.designer.languages.java.jdt.texteditor/src/org/eclipse/papyrus/designer/languages/java/jdt/texteditor/AddProfileAndModelLibsHandler.java
@@ -0,0 +1,146 @@
+/*******************************************************************************
+ * 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 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Ansgar Radermacher - ansgar.radermacher@cea.fr CEA LIST - initial API and implementation
+ *
+ *******************************************************************************/
+
+package org.eclipse.papyrus.designer.languages.java.jdt.texteditor;
+
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.emf.common.command.CommandStack;
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.edit.domain.EditingDomain;
+import org.eclipse.emf.transaction.RecordingCommand;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.emf.transaction.util.TransactionUtil;
+import org.eclipse.uml2.uml.Element;
+import org.eclipse.uml2.uml.Package;
+import org.eclipse.uml2.uml.PackageImport;
+import org.eclipse.uml2.uml.Profile;
+import org.eclipse.uml2.uml.UMLFactory;
+import org.eclipse.uml2.uml.resource.UMLResource;
+
+/**
+ * This class adds the C++ profile as well as the ANSI-C library to your model.
+ *
+ * TODO: currently not used.
+ */
+public class AddProfileAndModelLibsHandler {
+
+ static final String CPP_PROFILE_URI = "pathmap://CPP_PROFILES/C_Cpp.profile.uml"; //$NON-NLS-1$
+
+ static final String ANSIC_LIBRARY_URI = "pathmap://CPP_LIBRARIES/Ansi_C.library.uml"; //$NON-NLS-1$
+
+ /**
+ * Retrieve a model library from the repository
+ *
+ * @param uri
+ * the URI of the repository
+ * @param domain
+ * the editing library
+ *
+ * @return the package import created for a model library
+ */
+ public PackageImport getModelLibraryImportFromURI(URI uri, EditingDomain domain) {
+ // Try to reach model
+ Element root = getContent(uri, domain);
+ if (root instanceof Package) {
+
+ // Import model library
+ Package libToImport = (Package) root;
+ // create import package
+ PackageImport modelLibImport = UMLFactory.eINSTANCE.createPackageImport();
+ modelLibImport.setImportedPackage(libToImport);
+
+ return modelLibImport;
+ }
+ return null;
+ }
+
+ public static Element getContent(URI uri, EditingDomain domain) {
+ // Resource resource = getTransactionalEditingDomain ().getResourceSet().getResource (uri, true);
+ Resource resource = domain.getResourceSet().getResource(uri, true);
+ return getContent(resource);
+ }
+
+ public static Element getContent(Resource resource) {
+ EList<EObject> contentObj = resource.getContents();
+ if ((contentObj.size() > 0) && (contentObj.get(0) instanceof Element)) {
+ return (Element) contentObj.get(0);
+ }
+ return null;
+ }
+
+ /**
+ * Check whether a package import is already done
+ *
+ * @param selectedPkg
+ * @param pi
+ * @return
+ */
+ boolean isAlreadyImported(Package selectedPkg, PackageImport pi) {
+ for (PackageImport existingPI : selectedPkg.getPackageImports()) {
+ if ((existingPI.getImportedPackage() == null) ||
+ (pi.getImportedPackage() == null)) {
+ // import package are null (should not happen?!)
+ continue;
+ }
+ if ((existingPI.getImportedPackage().getName() == null) ||
+ (pi.getImportedPackage().getName() == null)) {
+ // import package name not set (should not happen?!)
+ continue;
+ } else if (existingPI.getImportedPackage().getName().equals(pi.getImportedPackage().getName())) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Add C++ profile and package import for ANSI-C library
+ *
+ * @param selectedPkg
+ * the package to which the profile should be applied
+ * @throws ExecutionException
+ */
+ public void addProfileAndImport(final Package selectedPkg) throws ExecutionException {
+
+ final TransactionalEditingDomain domain = TransactionUtil.getEditingDomain(selectedPkg);
+ CommandStack stack = domain.getCommandStack();
+ stack.execute(new RecordingCommand(domain, "Add C++ profile & ANSI-C library") { //$NON-NLS-1$
+ @Override
+ public void doExecute() {
+ // add primitive types
+ // create import package to primitiveType
+ PackageImport pi = getModelLibraryImportFromURI(URI.createURI(UMLResource.UML_PRIMITIVE_TYPES_LIBRARY_URI), domain);
+ selectedPkg.getPackageImports().add(pi);
+ addCppProfile(selectedPkg, domain);
+ };
+ });
+ }
+
+ public static void addCppProfile(Package selectedPkg, TransactionalEditingDomain domain) {
+
+ // Retrieve C++ profile
+ Profile cppProfile = (Profile) getContent(URI.createURI(CPP_PROFILE_URI), domain);
+
+ // Apply C++ profile to model
+ if (cppProfile instanceof Profile) {
+ Profile profile = selectedPkg.getAppliedProfile(cppProfile.getQualifiedName());
+ if ((profile == null) && (!cppProfile.getOwnedStereotypes().isEmpty())) {
+ selectedPkg.applyProfile(cppProfile);
+ }
+ }
+ }
+}
diff --git a/plugins/languages/java/org.eclipse.papyrus.designer.languages.java.jdt.texteditor/src/org/eclipse/papyrus/designer/languages/java/jdt/texteditor/TextEditorConstants.java b/plugins/languages/java/org.eclipse.papyrus.designer.languages.java.jdt.texteditor/src/org/eclipse/papyrus/designer/languages/java/jdt/texteditor/TextEditorConstants.java
new file mode 100644
index 0000000..77e5535
--- /dev/null
+++ b/plugins/languages/java/org.eclipse.papyrus.designer.languages.java.jdt.texteditor/src/org/eclipse/papyrus/designer/languages/java/jdt/texteditor/TextEditorConstants.java
@@ -0,0 +1,25 @@
+/*******************************************************************************
+ * Copyright (c) 2021 CEA LIST.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Ansgar Radermacher - ansgar.radermacher@cea.fr CEA LIST - initial API and implementation
+ *
+ *******************************************************************************/
+
+package org.eclipse.papyrus.designer.languages.java.jdt.texteditor;
+
+import java.util.regex.Pattern;
+
+public class TextEditorConstants {
+
+ /**
+ * Regular expression for accepted language for compatible JDT code generators
+ */
+ public static final Pattern JAVA = Pattern.compile("Java"); //$NON-NLS-1$
+}
diff --git a/plugins/languages/java/org.eclipse.papyrus.designer.languages.java.jdt.texteditor/src/org/eclipse/papyrus/designer/languages/java/jdt/texteditor/Utils.java b/plugins/languages/java/org.eclipse.papyrus.designer.languages.java.jdt.texteditor/src/org/eclipse/papyrus/designer/languages/java/jdt/texteditor/Utils.java
new file mode 100644
index 0000000..cf52d0f
--- /dev/null
+++ b/plugins/languages/java/org.eclipse.papyrus.designer.languages.java.jdt.texteditor/src/org/eclipse/papyrus/designer/languages/java/jdt/texteditor/Utils.java
@@ -0,0 +1,196 @@
+/*******************************************************************************
+ * 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 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Ansgar Radermacher - ansgar.radermacher@cea.fr CEA LIST - initial API and implementation
+ *
+ *******************************************************************************/
+
+package org.eclipse.papyrus.designer.languages.java.jdt.texteditor;
+
+import org.eclipse.papyrus.designer.languages.common.extensionpoints.GenerationConstants;
+import org.eclipse.uml2.uml.Element;
+import org.eclipse.uml2.uml.NamedElement;
+import org.eclipse.uml2.uml.Package;
+
+/**
+ * Collection of utility operations that are used by the CDT editor.
+ */
+public class Utils {
+
+ public static final String nsSep = "::"; //$NON-NLS-1$
+
+ /**
+ * Decrease the indentation of a text block. This function is used during synchronization, since
+ * the code within an opaque behavior is not indented, whereas the code of an operation within a
+ * file is indented with a tab.
+ */
+ public static String decreaseIndent(char[] contents, int start, int end) {
+ return decreaseIndent(contents, start, end, 4);
+ }
+
+ /**
+ * Decrease the indentation of a text block. This function is used during synchronization, since
+ * the code within an opaque behavior is not indented, whereas the code of an operation within a
+ * file is indented with a tab.
+ */
+ public static String decreaseIndent(char[] contents, int start, int end, int indentation) {
+ String newBlock = ""; //$NON-NLS-1$
+ boolean newLine = true;
+ int consume = 0;
+ for (int i = start; i < end; i++) {
+ char c = contents[i];
+
+ // consume either a tab or 4 spaces;
+ if (newLine && (c == '\t')) {
+ consume = 1;
+ }
+ else if (newLine && (c == ' ')) {
+ consume = indentation;
+ }
+ else if (consume == 0 || c != ' ') {
+ newBlock += c;
+ consume = 0;
+ } else if (c == ' ') {
+ consume--;
+ } else {
+ consume = 0;
+ }
+
+ if ((c == '\n') || (c == '\r')) {
+ newLine = true;
+ } else {
+ newLine = false;
+ }
+ }
+ return newBlock;
+ }
+
+ /**
+ * Get an element via its qualified name. Will find elements from the root
+ * model and elements in imported models. Also supports target model in
+ * which imports have been copied (while keeping the top-level name)
+ *
+ * @param root
+ * @param qualifiedName
+ * @return the named element (or null, if not found)
+ */
+ public static NamedElement getQualifiedElement(Package root,
+ String qualifiedName) {
+ NamedElement namedElement = null;
+ int index = qualifiedName.indexOf(nsSep);
+ if (index != -1) {
+ // first try using a path without top element (since
+ // getQualifiedElement is typically used for
+ // imported elements)
+ String remainder = qualifiedName.substring(index + 2);
+ namedElement = getQualifiedElement(root, remainder, qualifiedName);
+ }
+ if (namedElement == null) {
+ // try with complete name as path name, but assume that the element
+ // has been copied into the model,
+ // i.e. qualifiedName is prefixed by model name
+ namedElement = getQualifiedElement(root, qualifiedName,
+ root.getName() + nsSep + qualifiedName);
+ }
+ return namedElement;
+ }
+
+ /**
+ * Retrieve an element via its qualified name within a package The segments
+ * of the package may be non unique due to imports
+ *
+ * @return the found element, if it exists
+ */
+ public static NamedElement getQualifiedElement(Package root,
+ String remainingPath, String qualifiedName) {
+ if (root == null) {
+ return null;
+ }
+ if (!remainingPath.contains(nsSep)) {
+ for (NamedElement candidate : root.getMembers()) {
+ String name = candidate.getName();
+ if ((name != null) && name.equals(remainingPath)) {
+ if (candidate.getQualifiedName().equals(qualifiedName)) {
+ return candidate;
+ }
+ }
+ }
+ } else {
+ String segment = remainingPath.split(nsSep)[0];
+ String remainder = remainingPath.substring(segment.length() + 2);
+ for (Element element : root.getMembers()) {
+ if (element instanceof Package) {
+ if (((NamedElement) element).getName().equals(segment)) {
+ NamedElement foundElement = getQualifiedElement(
+ (Package) element, remainder, qualifiedName);
+ // return, if not found
+ if (foundElement != null) {
+ return foundElement;
+ }
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * return the top-level owner of an element. This function returns the same
+ * value as getModel, if the top-level element is a model. While this is the
+ * case for models, model libraries have a top-level package (not a model).
+ * In this case, getTop returns the top-level package whereas getModel would
+ * return null.
+ *
+ * @param element
+ * @return the top-level owning package
+ */
+ public static Package getTop(Element element) {
+ while (element != null) {
+ Element owner = element.getOwner();
+ if (owner == null) {
+ if (element instanceof Package) {
+ return (Package) element;
+ }
+ }
+ element = owner;
+ }
+ return null;
+ }
+
+ /**
+ * Remove generated code from a body (everything between the GENERATED_START flag
+ *
+ * @param bodyStr
+ * @return the code without the start and end tags
+ */
+ public static String removeGenerated(String bodyStr) {
+ for (;;) {
+ int startPos = bodyStr.indexOf(GenerationConstants.GENERATED_START);
+ if (startPos == -1) {
+ break;
+ }
+ // search line break of previous line (if any)
+ while ((startPos > 0) && bodyStr.charAt(startPos) != '\r' && bodyStr.charAt(startPos) != '\n') {
+ startPos--;
+ }
+ int endPos = bodyStr.indexOf(GenerationConstants.GENERATED_END, startPos);
+ if (endPos == -1) {
+ break;
+ }
+ endPos += GenerationConstants.GENERATED_END.length();
+ // stop at first non white-space character after comment.
+ while ((endPos < bodyStr.length()) && Character.isWhitespace(bodyStr.charAt(endPos))) {
+ endPos++;
+ }
+ bodyStr = bodyStr.substring(0, startPos) + bodyStr.substring(endPos);
+ }
+ return bodyStr;
+ }
+}
diff --git a/plugins/languages/java/org.eclipse.papyrus.designer.languages.java.jdt.texteditor/src/org/eclipse/papyrus/designer/languages/java/jdt/texteditor/editor/SyncJDTEditor.java b/plugins/languages/java/org.eclipse.papyrus.designer.languages.java.jdt.texteditor/src/org/eclipse/papyrus/designer/languages/java/jdt/texteditor/editor/SyncJDTEditor.java
new file mode 100644
index 0000000..8afddb7
--- /dev/null
+++ b/plugins/languages/java/org.eclipse.papyrus.designer.languages.java.jdt.texteditor/src/org/eclipse/papyrus/designer/languages/java/jdt/texteditor/editor/SyncJDTEditor.java
@@ -0,0 +1,248 @@
+/*****************************************************************************
+ * Copyright (c) 2013 CEA LIST.
+ *
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Ansgar Radermacher (CEA LIST) Ansgar.Radermacher@cea.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.designer.languages.java.jdt.texteditor.editor;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.ISourceRange;
+import org.eclipse.jdt.core.ISourceReference;
+import org.eclipse.jdt.internal.ui.javaeditor.CompilationUnitEditor;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.text.source.IOverviewRuler;
+import org.eclipse.jface.text.source.ISourceViewer;
+import org.eclipse.jface.text.source.IVerticalRuler;
+import org.eclipse.papyrus.designer.languages.java.jdt.texteditor.Activator;
+import org.eclipse.papyrus.designer.languages.java.jdt.texteditor.sync.ObtainICElement;
+import org.eclipse.papyrus.designer.languages.java.jdt.texteditor.sync.SyncJDTtoModel;
+import org.eclipse.papyrus.infra.core.services.ServiceException;
+import org.eclipse.papyrus.infra.core.services.ServicesRegistry;
+import org.eclipse.papyrus.infra.ui.editor.IMultiDiagramEditor;
+import org.eclipse.papyrus.infra.ui.lifecycleevents.DoSaveEvent;
+import org.eclipse.papyrus.infra.ui.lifecycleevents.ILifeCycleEventsProvider;
+import org.eclipse.papyrus.infra.ui.lifecycleevents.ISaveEventListener;
+import org.eclipse.papyrus.infra.ui.services.EditorLifecycleEventListener;
+import org.eclipse.papyrus.infra.ui.services.EditorLifecycleManager;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.events.FocusEvent;
+import org.eclipse.swt.events.FocusListener;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.uml2.uml.NamedElement;
+
+/**
+ * A specialization of the JDT (Class) editor made for integration into Papyrus
+ *
+ */
+@SuppressWarnings("restriction")
+public class SyncJDTEditor extends CompilationUnitEditor {
+
+ protected ILifeCycleEventsProvider lifeCycleEvents;
+
+ protected ISaveEventListener preSaveEvent;
+
+ /** the text listener */
+ protected FocusListener focusListener;
+
+ protected SyncJDTtoModel syncJava;
+
+ // a bar in different colors indicating whether synchronization
+ // is active.
+ protected Composite syncBar;
+
+ public static final RGB ORANGE = new RGB(240, 150, 100);
+
+ public static final RGB GREEN = new RGB(150, 230, 100);
+
+ public SyncJDTEditor() {
+ super();
+ }
+
+ /**
+ *
+ * initialize editor data
+ *
+ * @param registry
+ * Papyrus service registry
+ * @param syncJava
+ * reference to class that synchronizes the editor content with the model
+ */
+ public void setEditorData(final ServicesRegistry registry, final SyncJDTtoModel syncJava) {
+ try {
+ // synchronize, before the UML model is saved.
+ this.syncJava = syncJava;
+ lifeCycleEvents = registry.getService(ILifeCycleEventsProvider.class);
+ syncBar.setBackground(new Color(Display.getDefault(), GREEN));
+ preSaveEvent = new ISaveEventListener() {
+
+ @Override
+ public void doSaveAs(DoSaveEvent event) {
+ }
+
+ @Override
+ public void doSave(DoSaveEvent event) {
+ SyncJDTEditor.this.syncJava.syncCDTtoModel();
+ }
+ };
+ lifeCycleEvents.addAboutToDoSaveListener(preSaveEvent);
+
+ EditorLifecycleManager editorlifeCycle = registry.getService(EditorLifecycleManager.class);
+ EditorLifecycleEventListener closeListener = new EditorLifecycleEventListener() {
+
+ @Override
+ public void postInit(IMultiDiagramEditor editor) {
+ }
+
+ @Override
+ public void postDisplay(IMultiDiagramEditor editor) {
+ }
+
+ @Override
+ public void beforeClose(IMultiDiagramEditor editor) {
+ SyncJDTEditor.this.syncJava = null;
+ syncBar.setBackground(new Color(Display.getDefault(), ORANGE));
+ }
+ };
+ editorlifeCycle.addEditorLifecycleEventsListener(closeListener);
+
+ } catch (ServiceException e) {
+ Activator.log.error(e);
+ }
+ }
+
+ /**
+ *
+ * @see org.eclipse.ui.texteditor.AbstractDecoratedTextEditor#createSourceViewer(org.eclipse.swt.widgets.Composite, org.eclipse.jface.text.source.IVerticalRuler, int)
+ *
+ * @param parent
+ * @param ruler
+ * @param styles
+ * @return a source viewers
+ */
+ @Override
+ public ISourceViewer createJavaSourceViewer(Composite editorComposite, IVerticalRuler ruler, IOverviewRuler overviewRuler, boolean isOverviewRulerVisible, int styles, IPreferenceStore store) {
+
+ Composite parent = editorComposite.getParent();
+ // parent.setLayout(new GridLayout(2, false));
+ syncBar = new Composite(parent, SWT.NONE);
+
+ GridData barGD = new GridData();
+ barGD.heightHint = 5;
+ barGD.horizontalAlignment = GridData.FILL;
+ syncBar.setLayoutData(barGD);
+
+ final ISourceViewer viewer = super.createJavaSourceViewer(editorComposite, ruler, overviewRuler, isOverviewRulerVisible, styles, store);
+ GridData editorGD = new GridData();
+ editorGD.horizontalAlignment = GridData.FILL;
+ editorGD.verticalAlignment = GridData.FILL;
+ editorGD.grabExcessHorizontalSpace = true;
+ editorGD.grabExcessVerticalSpace = true;
+ // parent.getChildren()[1].setLayoutData(editorGD);
+
+ // parent.setBackground(new Color(Display.getDefault(), ORANGE));
+ syncBar.setBackground(new Color(Display.getDefault(), ORANGE));
+ parent.pack();
+ // Composite composite = parent;
+ // while (composite != null) {
+ // if (composite instanceof CTabFolder) {
+ // CTabFolder tabFolder = (CTabFolder) composite;
+ // CTabItem t = tabFolder.getItem(tabFolder.getItemCount() - 1);
+ // Control tabFolders[] = tabFolder.getParent().getChildren();
+ // if (tabFolders.length == 1) {
+ // // TODO: create a 2nd tabFolder and move element. Unclear side-effects => not done
+ // CTabFolder right = new CTabFolder(folder.getParent(), SWT.RIGHT);
+ // }
+ // }
+ // composite = composite.getParent();
+ // }
+
+ focusListener = new FocusListener() {
+
+ @Override
+ public void focusLost(FocusEvent e) {
+ // potential problem for undo/redo!!
+ if (isDirty() && syncJava != null) {
+ // by saving, we assure that the editor automatically updates when the file is re-generated due
+ // to model changes. Otherwise, the user will get a popup whether he wants to load changed the changed
+ // file (and loose editor contents).
+ // Currently, the is-dirty flag is used to detect whether contents need to be synchronized to the model.
+ // If we stop saving automatically on focus lost, we would need to add another detection.
+ //
+ doSave(new NullProgressMonitor());
+ syncJava.syncCDTtoModel();
+ }
+ }
+
+ @Override
+ public void focusGained(FocusEvent e) {
+ }
+ };
+ // register focus listener
+ viewer.getTextWidget().addFocusListener(focusListener);
+
+ return viewer;
+ }
+
+ /**
+ * Goto a specific element within the text editor. Currently, only methods are supported.
+ *
+ * @param element
+ * a named UML element
+ */
+ public void gotoElement(NamedElement element) {
+ IJavaElement inputJE = getInputJavaElement();
+ if (inputJE instanceof ICompilationUnit) {
+ ICompilationUnit icu = (ICompilationUnit) inputJE;
+ IJavaElement icElement = ObtainICElement.getIJavaElement(syncJava.getCodeGen(), icu, element);
+ if (icElement instanceof ISourceReference) {
+ try {
+ ISourceRange range = ((ISourceReference) icElement).getSourceRange();
+
+ ISourceViewer viewer = getSourceViewer();
+ viewer.revealRange(range.getOffset(), 1);
+ viewer.setSelectedRange(range.getOffset(), range.getLength());
+ return;
+ } catch (CoreException e) {
+ Activator.log.error(e);
+ }
+ }
+ }
+ }
+
+ /**
+ *
+ * @see org.eclipse.ui.editors.text.TextEditor#dispose()
+ *
+ */
+ @Override
+ public void dispose() {
+ // we remove the listener
+ StyledText st = getSourceViewer().getTextWidget();
+ if (st != null && focusListener != null) {
+ st.removeFocusListener(focusListener);
+ }
+
+ // remove save event listener
+ if (lifeCycleEvents != null) {
+ lifeCycleEvents.removeAboutToDoSaveListener(preSaveEvent);
+ }
+ }
+}
diff --git a/plugins/languages/java/org.eclipse.papyrus.designer.languages.java.jdt.texteditor/src/org/eclipse/papyrus/designer/languages/java/jdt/texteditor/handler/SyncJDTEditorHandler.java b/plugins/languages/java/org.eclipse.papyrus.designer.languages.java.jdt.texteditor/src/org/eclipse/papyrus/designer/languages/java/jdt/texteditor/handler/SyncJDTEditorHandler.java
new file mode 100644
index 0000000..721625b
--- /dev/null
+++ b/plugins/languages/java/org.eclipse.papyrus.designer.languages.java.jdt.texteditor/src/org/eclipse/papyrus/designer/languages/java/jdt/texteditor/handler/SyncJDTEditorHandler.java
@@ -0,0 +1,225 @@
+/*****************************************************************************
+ * Copyright (c) 2012, 2016 CEA LIST, Christian W. Damus, and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Vincent Lorenzo (CEA LIST) Vincent.Lorenzo@cea.fr - Initial API and implementation
+ * Ansgar Radermacher (CEA LIST) ansgar.radermacher@cea.fr
+ * Christian W. Damus - bug 485220
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.designer.languages.java.jdt.texteditor.handler;
+
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.emf.workspace.AbstractEMFOperation;
+import org.eclipse.papyrus.designer.languages.common.extensionpoints.ILangCodegen;
+import org.eclipse.papyrus.designer.languages.common.extensionpoints.LanguageCodegen;
+import org.eclipse.papyrus.designer.languages.java.jdt.texteditor.Activator;
+import org.eclipse.papyrus.designer.languages.java.jdt.texteditor.TextEditorConstants;
+import org.eclipse.papyrus.designer.languages.java.jdt.texteditor.editor.SyncJDTEditor;
+import org.eclipse.papyrus.designer.languages.java.jdt.texteditor.sync.SyncJDTtoModel;
+import org.eclipse.papyrus.designer.languages.java.jdt.texteditor.sync.SyncModelToJDT;
+import org.eclipse.papyrus.infra.core.resource.NotFoundException;
+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.gmf.command.CheckedOperationHistory;
+import org.eclipse.papyrus.infra.ui.util.ServiceUtilsForHandlers;
+import org.eclipse.papyrus.uml.diagram.common.handlers.CmdHandler;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.part.FileEditorInput;
+import org.eclipse.uml2.uml.Behavior;
+import org.eclipse.uml2.uml.Class;
+import org.eclipse.uml2.uml.Classifier;
+import org.eclipse.uml2.uml.Element;
+import org.eclipse.uml2.uml.Operation;
+import org.eclipse.uml2.uml.Transition;
+import org.eclipse.uml2.uml.UMLPackage;
+
+
+/**
+ * The handler creates a new JDT editor
+ */
+public class SyncJDTEditorHandler extends CmdHandler {
+
+
+ private static final String EDITOR_ID = "org.eclipse.papyrus.designer.languages.java.jdt.texteditor.editor.SyncJDTEditor"; //$NON-NLS-1$
+
+ public SyncJDTEditorHandler() {
+ }
+
+ /**
+ * @see org.eclipse.core.commands.AbstractHandler#isEnabled()
+ *
+ * @return true, if enabled
+ */
+ @Override
+ public boolean isEnabled() {
+ updateSelectedEObject();
+ // Filter Classes (including Behaviors, since Behavior inherits from Class), Operation and Transition
+ if (selectedEObject instanceof Class ||
+ selectedEObject instanceof Operation ||
+ selectedEObject instanceof Transition) {
+
+ URI uri = selectedEObject.eResource().getURI();
+ // URI must have at least two segments (must be in a project)
+ return uri.segmentCount() >= 2;
+ }
+ return false;
+ }
+
+ /**
+ * @see org.eclipse.core.commands.IHandler#execute(org.eclipse.core.commands.ExecutionEvent)
+ *
+ * @param event
+ * an execution event
+ * @return the execution result
+ * @throws ExecutionException
+ */
+ @Override
+ public Object execute(final ExecutionEvent event) throws ExecutionException {
+ try {
+ final ServicesRegistry serviceRegistry = ServiceUtilsForHandlers.getInstance().getServiceRegistry(event);
+ TransactionalEditingDomain domain = ServiceUtils.getInstance().getTransactionalEditingDomain(serviceRegistry);
+
+ // Create the transactional command
+ AbstractEMFOperation command = new AbstractEMFOperation(domain, "Create JDT editor") { //$NON-NLS-1$
+
+ @Override
+ protected IStatus doExecute(final IProgressMonitor monitor, final IAdaptable info) throws ExecutionException {
+ try {
+ SyncJDTEditorHandler.this.doExecute(serviceRegistry);
+ } catch (ServiceException e) {
+ Activator.log.error(e);
+ return Status.CANCEL_STATUS;
+ } catch (NotFoundException e) {
+ Activator.log.error(e);
+ return Status.CANCEL_STATUS;
+ }
+ return Status.OK_STATUS;
+ }
+ };
+
+ // Execute the command
+ CheckedOperationHistory.getInstance().execute(command, new NullProgressMonitor(), null);
+ } catch (ExecutionException e) {
+ Activator.log.error("Can't create a JDT editor", e); //$NON-NLS-1$
+ } catch (ServiceException e) {
+ Activator.log.error("Service exception during creation of CDT editor", e); //$NON-NLS-1$
+ }
+ return null;
+ }
+
+
+ /**
+ * Do the execution of the command.
+ *
+ * @param serviceRegistry
+ * @throws ServiceException
+ * @throws NotFoundException
+ */
+ public void doExecute(final ServicesRegistry serviceRegistry) throws ServiceException, NotFoundException {
+ Classifier classifierToEdit = getClassifierToEdit();
+ // Fixed ID, since synchronization only works for standard C++ code generator
+ final ILangCodegen codegen =
+ LanguageCodegen.getGenerator(TextEditorConstants.JAVA, null);
+ if (codegen == null) {
+ return;
+ }
+
+ if (selectedEObject instanceof Transition) {
+ Transition transition = (Transition) selectedEObject;
+ if (transition.getEffect() == null) {
+ transition.createEffect("effectOf" + transition.getName(), UMLPackage.eINSTANCE.getOpaqueBehavior()); //$NON-NLS-1$
+ }
+ }
+
+ // make sure that target project gets generated
+ codegen.getTargetProject(classifierToEdit, true);
+ IFile srcFile = SyncModelToJDT.syncModelToCDT(classifierToEdit, LanguageCodegen.getID(codegen));
+ if (srcFile == null) {
+ return;
+ }
+
+ Display.getDefault().asyncExec(new Runnable() {
+
+ @Override
+ public void run() {
+ IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
+ try {
+ // IEditorPart editorPart = page.openEditor(new FileEditorInput(srcFile), "org.eclipse.cdt.ui.editor.CEditor");
+
+ IEditorInput input = new FileEditorInput(srcFile);
+ IEditorPart editorPart = page.openEditor(input, EDITOR_ID);
+ if (editorPart instanceof SyncJDTEditor) {
+ // TODO: use editorPart.setInitializationData(cfig, propertyName, data);
+ URI uri = selectedEObject.eResource().getURI();
+ SyncJDTtoModel syncCpp =
+ new SyncJDTtoModel(input, classifierToEdit, URI.decode(uri.segment(1)), LanguageCodegen.getID(codegen));
+
+ ((SyncJDTEditor) editorPart).setEditorData(serviceRegistry, syncCpp);
+ }
+ } catch (PartInitException e) {
+ Activator.log.error(e);
+ }
+ // move page to the RIGHT
+
+// if (rootModel instanceof TabFolder) {
+// // root = tabFolder, i.e. there is a single folder
+// ISashWindowsContainer sashContainer = ServiceUtils.getInstance().getService(ISashWindowsContainer.class, serviceRegistry);
+// int index = lookupIndex((TabFolder) rootModel, editorModelFinal);
+// if (index != -1) {
+// sashContentProvider.createFolder(sashContainer.getSelectedTabFolderModel(), index, sashContainer.getSelectedTabFolderModel(), SWT.RIGHT);
+// }
+// }
+ }
+ });
+
+ }
+
+ /**
+ * The classifier to edit - corresponding to the selected object.
+ *
+ * @return
+ */
+ protected Classifier getClassifierToEdit() {
+ if (selectedEObject instanceof Operation) {
+ return ((Operation) selectedEObject).getFeaturingClassifiers().get(0);
+ } else if (selectedEObject instanceof Transition) {
+ return ((Transition) selectedEObject).getContainer().getStateMachine().getContext();
+ } else if (selectedEObject instanceof Behavior) {
+ Element owner = (Behavior) selectedEObject;
+ while (owner != null) {
+ owner = owner.getOwner();
+ if ((owner instanceof Classifier) && !(owner instanceof Behavior)) {
+ return (Classifier) owner;
+ }
+ }
+ return null;
+ } else if (selectedEObject instanceof Classifier) {
+ // must be class or datatype
+ return (Classifier) selectedEObject;
+ }
+ return null;
+ }
+}
diff --git a/plugins/languages/java/org.eclipse.papyrus.designer.languages.java.jdt.texteditor/src/org/eclipse/papyrus/designer/languages/java/jdt/texteditor/listener/ChangeKind.java b/plugins/languages/java/org.eclipse.papyrus.designer.languages.java.jdt.texteditor/src/org/eclipse/papyrus/designer/languages/java/jdt/texteditor/listener/ChangeKind.java
new file mode 100644
index 0000000..9f14533
--- /dev/null
+++ b/plugins/languages/java/org.eclipse.papyrus.designer.languages.java.jdt.texteditor/src/org/eclipse/papyrus/designer/languages/java/jdt/texteditor/listener/ChangeKind.java
@@ -0,0 +1,15 @@
+/**
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.eclipse.papyrus.designer.languages.java.jdt.texteditor.listener;
+
+public enum ChangeKind {
+ INTERFACE,
+ IMPLEMENTATION,
+ OPERATION
+};
diff --git a/plugins/languages/java/org.eclipse.papyrus.designer.languages.java.jdt.texteditor/src/org/eclipse/papyrus/designer/languages/java/jdt/texteditor/listener/Closure.java b/plugins/languages/java/org.eclipse.papyrus.designer.languages.java.jdt.texteditor/src/org/eclipse/papyrus/designer/languages/java/jdt/texteditor/listener/Closure.java
new file mode 100644
index 0000000..0d5969f
--- /dev/null
+++ b/plugins/languages/java/org.eclipse.papyrus.designer.languages.java.jdt.texteditor/src/org/eclipse/papyrus/designer/languages/java/jdt/texteditor/listener/Closure.java
@@ -0,0 +1,83 @@
+/*****************************************************************************
+ * Copyright (c) 2013 CEA LIST.
+ *
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Ansgar Radermacher (CEA LIST) Ansgar.Radermacher@cea.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+
+package org.eclipse.papyrus.designer.languages.java.jdt.texteditor.listener;
+
+import org.eclipse.emf.common.util.BasicEList;
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EStructuralFeature.Setting;
+import org.eclipse.uml2.common.util.UML2Util;
+import org.eclipse.uml2.uml.Association;
+import org.eclipse.uml2.uml.Classifier;
+import org.eclipse.uml2.uml.Element;
+
+/**
+ * Calculate the closure of classifiers that need to be re-generated, if a
+ * classifier changes
+ *
+ * There are two different reasons for the need to re-generate a classifier:
+ * (1) one of the elements that it contains has changed
+ * (2) an element outside the containment close is changed. An example is a superclass
+ * that changes its name or an association target. In many cases, classifier depend
+ * on names of outside elements, but the also require a regeneration if the element
+ * is deleted.
+ * We need to take the change-kind into account. E.g. if the name of an operation in A changes, we need to
+ * re-generate class A, but we only need to regenerate class B (inheriting from A), if it actually
+ * redefines that operation.
+ */
+public class Closure {
+ public static EList<Classifier> calc(Classifier cl) {
+ EList<Classifier> list = new BasicEList<Classifier>();
+ calc(cl, list);
+ return list;
+ }
+
+ public static void calc(Classifier cl, EList<Classifier> list) {
+ if (cl != null) {
+ for (Setting setting : UML2Util.getNonNavigableInverseReferences(cl)) {
+ EObject eObj = setting.getEObject();
+ if (eObj instanceof Element) {
+ Classifier referencedCl = nearestClassifier(eObj);
+ if (!list.contains(referencedCl) && (!(referencedCl instanceof Association))) {
+ list.add(referencedCl);
+ calc(referencedCl, list);
+ }
+ }
+ }
+ }
+ }
+
+ public static boolean isContained(EObject parent, EObject possibleChild) {
+ while (possibleChild != null) {
+ if (parent == possibleChild) {
+ return true;
+ }
+ possibleChild = possibleChild.eContainer();
+ }
+ return false;
+ }
+
+ public static Classifier nearestClassifier(EObject eObj) {
+ while (eObj != null) {
+ if (eObj instanceof Classifier) {
+ return (Classifier) eObj;
+ }
+ eObj = eObj.eContainer();
+ }
+ return null;
+ }
+}
diff --git a/plugins/languages/java/org.eclipse.papyrus.designer.languages.java.jdt.texteditor/src/org/eclipse/papyrus/designer/languages/java/jdt/texteditor/listener/ModelListener.java b/plugins/languages/java/org.eclipse.papyrus.designer.languages.java.jdt.texteditor/src/org/eclipse/papyrus/designer/languages/java/jdt/texteditor/listener/ModelListener.java
new file mode 100644
index 0000000..67863a9
--- /dev/null
+++ b/plugins/languages/java/org.eclipse.papyrus.designer.languages.java.jdt.texteditor/src/org/eclipse/papyrus/designer/languages/java/jdt/texteditor/listener/ModelListener.java
@@ -0,0 +1,135 @@
+/*****************************************************************************
+ * Copyright (c) 2013 CEA LIST.
+ *
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Ansgar Radermacher (CEA LIST) Ansgar.Radermacher@cea.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+
+package org.eclipse.papyrus.designer.languages.java.jdt.texteditor.listener;
+
+import org.eclipse.emf.common.notify.Notification;
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.common.util.UniqueEList;
+import org.eclipse.papyrus.designer.languages.java.jdt.texteditor.Activator;
+import org.eclipse.papyrus.infra.core.listenerservice.IPapyrusListener;
+import org.eclipse.papyrus.uml.tools.listeners.PapyrusStereotypeListener;
+import org.eclipse.uml2.uml.Behavior;
+import org.eclipse.uml2.uml.Classifier;
+import org.eclipse.uml2.uml.DirectedRelationship;
+import org.eclipse.uml2.uml.Element;
+import org.eclipse.uml2.uml.Feature;
+import org.eclipse.uml2.uml.Package;
+import org.eclipse.uml2.uml.Parameter;
+
+/**
+ * Main listener for model changes (registered via plugin.xml). It will delegate
+ * to the sub-listeners for specific sub-elements (type, operation, port, ...) that
+ * can be found in this package
+ */
+@SuppressWarnings("deprecation") // TODO: replace with StereotypeElementListener
+public class ModelListener implements IPapyrusListener {
+
+ /**
+ * set to true, if a synchronization from an CDT editor to the model is active
+ */
+ public static boolean syncFromEditor;
+
+ @Override
+ public void notifyChanged(Notification notification) {
+ Object notifier = notification.getNotifier();
+ int eventType = notification.getEventType();
+ if (syncFromEditor) {
+ return;
+ }
+ if ((eventType == Notification.REMOVING_ADAPTER) ||
+ (eventType == Notification.RESOLVE)) {
+ // does not indicate a modification of the element
+ return;
+ }
+
+ OperationHistoryListener.init();
+ try {
+ if (notifier instanceof Classifier) {
+ Classifier classifier = (Classifier) notifier;
+ if ((eventType == Notification.REMOVE) ||
+ (eventType == PapyrusStereotypeListener.MODIFIED_STEREOTYPE)) {
+ regenList.add(getNearestClassifier(classifier));
+ }
+ // don't treat addition here, since operations/properties do not have their final names yet
+ // IStorage storage = new TextStorage(string);
+ }
+ if (notifier instanceof Behavior) {
+ Behavior behavior = (Behavior) notifier;
+ if (eventType == Notification.SET) {
+ // name modification
+ if (behavior.getSpecification() == null) {
+ }
+ } else if (eventType == Notification.ADD) {
+ // modification of an opaque behavior in Papyrus implied remove&add operations
+ Classifier nearestCl = getNearestClassifier(behavior);
+ if (nearestCl != null) {
+ regenList.add(nearestCl);
+ }
+ }
+ }
+
+ else if (notifier instanceof Feature) {
+ // if a feature is added, it is first generated with a dummy name, then the name is corrected.
+ Feature feature = (Feature) notifier;
+ Element owner = feature.getOwner();
+ if (owner instanceof Classifier) {
+ regenList.add(getNearestClassifier(owner));
+ }
+ } else if (notifier instanceof Parameter) {
+ Parameter parameter = (Parameter) notifier;
+ if (parameter.getOperation() != null) {
+ Element owner = parameter.getOperation().getOwner();
+ if (owner instanceof Classifier) {
+ // System.out.println(owner);
+ regenList.add((Classifier) owner);
+ }
+ }
+ } else if (notifier instanceof DirectedRelationship) {
+ // if a feature is added, it is first generated with a dummy name, then the name is corrected.
+ DirectedRelationship dr = (DirectedRelationship) notifier;
+ for (Element client : dr.getSources()) {
+ if (client instanceof Classifier) {
+ regenList.add(getNearestClassifier(client));
+ }
+ }
+ } else if (notifier instanceof Package) {
+ }
+ } catch (Exception e) {
+ Activator.log.error(e);
+ }
+ }
+
+ /**
+ * Navigate to the nearest classifier. This function is useful, as behaviors are also
+ * classifiers and we want to avoid regenerating code for owned behaviors
+ *
+ * @param element
+ * a UML element
+ * @return the nearest element (in the containment hierarchy) that is a classifier but not a behavior
+ */
+ public static Classifier getNearestClassifier(Element element) {
+ while (element != null) {
+ if (!(element instanceof Behavior) && (element instanceof Classifier)) {
+ return (Classifier) element;
+ }
+ element = element.getOwner();
+ }
+ return null;
+ }
+
+ static EList<Classifier> regenList = new UniqueEList<Classifier>();
+}
diff --git a/plugins/languages/java/org.eclipse.papyrus.designer.languages.java.jdt.texteditor/src/org/eclipse/papyrus/designer/languages/java/jdt/texteditor/listener/OperationHistoryListener.java b/plugins/languages/java/org.eclipse.papyrus.designer.languages.java.jdt.texteditor/src/org/eclipse/papyrus/designer/languages/java/jdt/texteditor/listener/OperationHistoryListener.java
new file mode 100644
index 0000000..d60d9ee
--- /dev/null
+++ b/plugins/languages/java/org.eclipse.papyrus.designer.languages.java.jdt.texteditor/src/org/eclipse/papyrus/designer/languages/java/jdt/texteditor/listener/OperationHistoryListener.java
@@ -0,0 +1,56 @@
+/*****************************************************************************
+ * Copyright (c) 2013 CEA LIST.
+ *
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Ansgar Radermacher (CEA LIST) Ansgar.Radermacher@cea.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+
+package org.eclipse.papyrus.designer.languages.java.jdt.texteditor.listener;
+
+import org.eclipse.core.commands.operations.IOperationHistoryListener;
+import org.eclipse.core.commands.operations.OperationHistoryEvent;
+import org.eclipse.core.commands.operations.OperationHistoryFactory;
+import org.eclipse.emf.common.util.BasicEList;
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.papyrus.designer.languages.java.jdt.texteditor.sync.SyncModelToJDT;
+import org.eclipse.uml2.uml.Classifier;
+
+public class OperationHistoryListener implements IOperationHistoryListener {
+
+ public static void init() {
+ if (ohl == null) {
+ ohl = new OperationHistoryListener();
+ OperationHistoryFactory.getOperationHistory().addOperationHistoryListener(ohl);
+ }
+ }
+
+ private static OperationHistoryListener ohl = null;
+
+ @Override
+ public void historyNotification(OperationHistoryEvent event) {
+ int eventType = event.getEventType();
+ if (eventType == OperationHistoryEvent.OPERATION_ADDED || eventType == OperationHistoryEvent.REDONE
+ || eventType == OperationHistoryEvent.UNDONE) {
+
+ EList<Classifier> regenListCopy = new BasicEList<Classifier>(ModelListener.regenList);
+ ModelListener.regenList.clear();
+
+ // re-generate files from list - if they are still in a resource
+ for (Classifier cl : regenListCopy) {
+ if (cl.eResource() != null) {
+ // sync. assumes that standard C++ generator
+ SyncModelToJDT.syncModelToCDT(cl, null);
+ }
+ }
+ }
+ }
+}
diff --git a/plugins/languages/java/org.eclipse.papyrus.designer.languages.java.jdt.texteditor/src/org/eclipse/papyrus/designer/languages/java/jdt/texteditor/preferences/CDTPreferenceConstants.java b/plugins/languages/java/org.eclipse.papyrus.designer.languages.java.jdt.texteditor/src/org/eclipse/papyrus/designer/languages/java/jdt/texteditor/preferences/CDTPreferenceConstants.java
new file mode 100644
index 0000000..4add456
--- /dev/null
+++ b/plugins/languages/java/org.eclipse.papyrus.designer.languages.java.jdt.texteditor/src/org/eclipse/papyrus/designer/languages/java/jdt/texteditor/preferences/CDTPreferenceConstants.java
@@ -0,0 +1,35 @@
+/*****************************************************************************
+ * Copyright (c) 2013 CEA LIST.
+ *
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * CEA LIST - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.designer.languages.java.jdt.texteditor.preferences;
+
+/**
+ * Constant definitions for plug-in preferences
+ */
+public class CDTPreferenceConstants {
+
+ /**
+ * Default option for opening the editor at a specified location. Store uses directly the SWT constants
+ */
+ public static final String P_OPEN_LOCATION = "openLocation"; //$NON-NLS-1$
+
+ /**
+ * For attributes, the default "aggregation kind" value is "none". When this option is set
+ * it will be treated as composite
+ */
+ public static final String P_SYNC_PERMANENTLY = "syncPermanently"; //$NON-NLS-1$
+
+ public static final String P_SYNC_ALL_FILES = "syncAllFiles"; //$NON-NLS-1$
+}
diff --git a/plugins/languages/java/org.eclipse.papyrus.designer.languages.java.jdt.texteditor/src/org/eclipse/papyrus/designer/languages/java/jdt/texteditor/preferences/CDTPreferenceInitializer.java b/plugins/languages/java/org.eclipse.papyrus.designer.languages.java.jdt.texteditor/src/org/eclipse/papyrus/designer/languages/java/jdt/texteditor/preferences/CDTPreferenceInitializer.java
new file mode 100644
index 0000000..7c38f9d
--- /dev/null
+++ b/plugins/languages/java/org.eclipse.papyrus.designer.languages.java.jdt.texteditor/src/org/eclipse/papyrus/designer/languages/java/jdt/texteditor/preferences/CDTPreferenceInitializer.java
@@ -0,0 +1,41 @@
+/*****************************************************************************
+ * Copyright (c) 2013 CEA LIST.
+ *
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * CEA LIST - Initial API and implementation
+ *
+ *****************************************************************************/
+
+package org.eclipse.papyrus.designer.languages.java.jdt.texteditor.preferences;
+
+import org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.papyrus.designer.languages.java.jdt.texteditor.Activator;
+import org.eclipse.swt.SWT;
+
+/**
+ * Class used to initialize default preference values.
+ */
+public class CDTPreferenceInitializer extends AbstractPreferenceInitializer {
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer#initializeDefaultPreferences()
+ */
+ @Override
+ public void initializeDefaultPreferences() {
+ IPreferenceStore store = Activator.getDefault().getPreferenceStore();
+ store.setDefault(CDTPreferenceConstants.P_OPEN_LOCATION, SWT.RIGHT);
+ store.setDefault(CDTPreferenceConstants.P_SYNC_ALL_FILES, false);
+ store.setDefault(CDTPreferenceConstants.P_SYNC_PERMANENTLY, false);
+ }
+}
diff --git a/plugins/languages/java/org.eclipse.papyrus.designer.languages.java.jdt.texteditor/src/org/eclipse/papyrus/designer/languages/java/jdt/texteditor/preferences/CDTPreferencePage.java b/plugins/languages/java/org.eclipse.papyrus.designer.languages.java.jdt.texteditor/src/org/eclipse/papyrus/designer/languages/java/jdt/texteditor/preferences/CDTPreferencePage.java
new file mode 100644
index 0000000..aa938d2
--- /dev/null
+++ b/plugins/languages/java/org.eclipse.papyrus.designer.languages.java.jdt.texteditor/src/org/eclipse/papyrus/designer/languages/java/jdt/texteditor/preferences/CDTPreferencePage.java
@@ -0,0 +1,66 @@
+/*****************************************************************************
+ * Copyright (c) 2013 CEA LIST.
+ *
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * CEA LIST - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.designer.languages.java.jdt.texteditor.preferences;
+
+import org.eclipse.jface.preference.BooleanFieldEditor;
+import org.eclipse.jface.preference.FieldEditorPreferencePage;
+import org.eclipse.papyrus.designer.languages.java.jdt.texteditor.Activator;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPreferencePage;
+
+
+/**
+ * This class represents the EC3M preference page
+ * <p>
+ * This page is used to modify preferences only. They are stored in the preference store that belongs to the main plug-in class. That way, preferences can be accessed directly via the preference store.
+ */
+
+public class CDTPreferencePage
+ extends FieldEditorPreferencePage
+ implements IWorkbenchPreferencePage {
+
+ public CDTPreferencePage() {
+ super(GRID);
+ setPreferenceStore(Activator.getDefault().getPreferenceStore());
+ setDescription("CDT editor integration options"); //$NON-NLS-1$
+ }
+
+ /**
+ * Creates the field editors. Field editors are abstractions of
+ * the common GUI blocks needed to manipulate various types
+ * of preferences. Each field editor knows how to save and
+ * restore itself.
+ */
+ @Override
+ public void createFieldEditors() {
+ addField(new BooleanFieldEditor(
+ CDTPreferenceConstants.P_SYNC_PERMANENTLY, "&Synchronize permanently (otherwise only on demand)", //$NON-NLS-1$
+ getFieldEditorParent()));
+
+ addField(new BooleanFieldEditor(
+ CDTPreferenceConstants.P_SYNC_ALL_FILES, "Synchronize all classes (otherwise synchronize only classes with open editor)", //$NON-NLS-1$
+ getFieldEditorParent()));
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.IWorkbenchPreferencePage#init(org.eclipse.ui.IWorkbench)
+ */
+ @Override
+ public void init(IWorkbench workbench) {
+ }
+}
diff --git a/plugins/languages/java/org.eclipse.papyrus.designer.languages.java.jdt.texteditor/src/org/eclipse/papyrus/designer/languages/java/jdt/texteditor/sync/FindTransition.java b/plugins/languages/java/org.eclipse.papyrus.designer.languages.java.jdt.texteditor/src/org/eclipse/papyrus/designer/languages/java/jdt/texteditor/sync/FindTransition.java
new file mode 100644
index 0000000..6816a75
--- /dev/null
+++ b/plugins/languages/java/org.eclipse.papyrus.designer.languages.java.jdt.texteditor/src/org/eclipse/papyrus/designer/languages/java/jdt/texteditor/sync/FindTransition.java
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * Copyright (c) 2013 CEA LIST.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Ansgar Radermacher - ansgar.radermacher@cea.fr CEA LIST - initial API and implementation
+ *
+ *******************************************************************************/
+
+package org.eclipse.papyrus.designer.languages.java.jdt.texteditor.sync;
+
+import org.eclipse.uml2.uml.Behavior;
+import org.eclipse.uml2.uml.Classifier;
+import org.eclipse.uml2.uml.Element;
+import org.eclipse.uml2.uml.NamedElement;
+import org.eclipse.uml2.uml.Transition;
+
+/**
+ * Find the behavior in the model from a given method in the code. Used during the
+ * back synchronization from code to model.
+ */
+public class FindTransition {
+
+ private static final String UNDERSCORE = "_"; //$NON-NLS-1$
+
+ public static Behavior findBehavior(Classifier cl, String methodName) {
+ for (Element element : cl.allOwnedElements()) {
+ if (element instanceof Transition) {
+ Transition transition = (Transition) element;
+ Behavior effect = transition.getEffect();
+ if ((effect != null) && behaviorMatches(effect, methodName)) {
+ return transition.getEffect();
+ }
+ }
+ }
+ return null;
+ }
+
+ public static boolean behaviorMatches(Behavior behavior, String methodName) {
+ return
+ methodName.endsWith(NamedElement.SEPARATOR + behavior.getName()) ||
+ methodName.endsWith(UNDERSCORE + behavior.getName());
+ }
+}
diff --git a/plugins/languages/java/org.eclipse.papyrus.designer.languages.java.jdt.texteditor/src/org/eclipse/papyrus/designer/languages/java/jdt/texteditor/sync/ObtainICElement.java b/plugins/languages/java/org.eclipse.papyrus.designer.languages.java.jdt.texteditor/src/org/eclipse/papyrus/designer/languages/java/jdt/texteditor/sync/ObtainICElement.java
new file mode 100644
index 0000000..70a3e08
--- /dev/null
+++ b/plugins/languages/java/org.eclipse.papyrus.designer.languages.java.jdt.texteditor/src/org/eclipse/papyrus/designer/languages/java/jdt/texteditor/sync/ObtainICElement.java
@@ -0,0 +1,128 @@
+/*******************************************************************************
+ * 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 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Ansgar Radermacher - ansgar.radermacher@cea.fr CEA LIST - initial API and implementation
+ *
+ *******************************************************************************/
+
+package org.eclipse.papyrus.designer.languages.java.jdt.texteditor.sync;
+
+import java.util.Iterator;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IMethod;
+import org.eclipse.jdt.core.IParent;
+import org.eclipse.papyrus.designer.languages.common.extensionpoints.ILangCodegen;
+import org.eclipse.papyrus.designer.languages.common.extensionpoints.MethodInfo;
+import org.eclipse.uml2.uml.Behavior;
+import org.eclipse.uml2.uml.NamedElement;
+import org.eclipse.uml2.uml.Operation;
+import org.eclipse.uml2.uml.Parameter;
+import org.eclipse.uml2.uml.ParameterDirectionKind;
+import org.eclipse.uml2.uml.Transition;
+
+
+/**
+ * This class is used to select the operation the user wants to edit after opening the editor.
+ * In case of transition, the selection is based on simple name only (either prefixed with the name separator or with an
+ * underscore - based on the assumption that scoped names are either kept or flattened using underscore as separator
+ *
+ */
+public class ObtainICElement {
+
+ /**
+ * Return the ICelement associated with a UML element. Currently, only methods are supported.
+ *
+ * @param parent
+ * the parent (typically the translation unit of a CDT file)
+ * @param element
+ * A named UML element
+ */
+ public static IJavaElement getIJavaElement(ILangCodegen codegen, IParent parent, NamedElement element) {
+ MethodInfo methodInfo = null;
+ NamedElement operationOrBehavior = element;
+ if (element instanceof Transition) {
+ operationOrBehavior = ((Transition) element).getEffect();
+ }
+
+ // no behavior found => not possible to locate element
+ if (operationOrBehavior == null) {
+ return null;
+ }
+
+ // get generator specific method info.
+ methodInfo = codegen.getMethodInfo(operationOrBehavior);
+
+ if (methodInfo == null) {
+ // use default behavior.
+ if (element instanceof Behavior) {
+ methodInfo = MethodInfo.fromBehavior((Behavior) operationOrBehavior);
+ }
+ else if (element instanceof Operation) {
+ methodInfo = MethodInfo.fromOperation((Operation) operationOrBehavior);
+ }
+ else {
+ return null;
+ }
+ }
+
+ try {
+ for (IJavaElement child : parent.getChildren()) {
+ if (child instanceof IParent) {
+ return getIJavaElement(codegen, (IParent) child, element);
+ }
+ if (child instanceof IMethod) {
+ IMethod function = (IMethod) child;
+
+ // does the element name match? (CDT provides className::methodName information). Since we are in the scope of
+ // the class, we only verify the postfix part of the name
+ if (child.getElementName().endsWith(NamedElement.SEPARATOR + methodInfo.getName())) {
+ // check, if parameters match. This handles most common overloading cases (it does not handle functions that
+ // only differ with respect to the modifiers
+ Iterator<String> paramIter = methodInfo.getParameterTypes().iterator();
+ boolean match = methodInfo.getParameterTypes().size() == function.getParameterTypes().length;
+ if (match) {
+ for (String cdtParamType : function.getParameterTypes()) {
+ String umlParamType = paramIter.next();
+ if (!cdtParamType.equals(umlParamType)) {
+ match = false;
+ break;
+ }
+ }
+ if (match) {
+ return child;
+ }
+ }
+ }
+ }
+ }
+ } catch (CoreException e) {
+ }
+ return null;
+ }
+
+ /**
+ * Count the number of parameters without taking the return parameter into account
+ *
+ * @param list
+ * @return the number of parameters (without return)
+ */
+ public static int countParameters(EList<Parameter> list) {
+ int params = 0;
+ for (Parameter par : list) {
+ if (par.getDirection() != ParameterDirectionKind.RETURN_LITERAL) {
+ params++;
+ }
+ }
+ return params;
+ }
+}
diff --git a/plugins/languages/java/org.eclipse.papyrus.designer.languages.java.jdt.texteditor/src/org/eclipse/papyrus/designer/languages/java/jdt/texteditor/sync/ParameterModifiers.java b/plugins/languages/java/org.eclipse.papyrus.designer.languages.java.jdt.texteditor/src/org/eclipse/papyrus/designer/languages/java/jdt/texteditor/sync/ParameterModifiers.java
new file mode 100644
index 0000000..d6c85a4
--- /dev/null
+++ b/plugins/languages/java/org.eclipse.papyrus.designer.languages.java.jdt.texteditor/src/org/eclipse/papyrus/designer/languages/java/jdt/texteditor/sync/ParameterModifiers.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Copyright (c) 2013 CEA LIST.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Ansgar Radermacher - ansgar.radermacher@cea.fr CEA LIST - initial API and implementation
+ *
+ *******************************************************************************/
+
+package org.eclipse.papyrus.designer.languages.java.jdt.texteditor.sync;
+
+/**
+ * Simple grouping of modifier related parameters
+ */
+public class ParameterModifiers {
+ public ParameterModifiers() {
+ isPointer = false;
+ isRef = false;
+ isRegister = false;
+ array = ""; //$NON-NLS-1$
+ }
+
+ /**
+ * true, if parameter is a pointer
+ */
+ public boolean isPointer;
+
+ /**
+ * true, if parameter is a reference
+ */
+ public boolean isRef;
+
+ /**
+ * true, if parameter is a register
+ */
+ public boolean isRegister;
+
+ /**
+ * value of array modifiers (e.g. [2])
+ */
+ public String array ;
+}
diff --git a/plugins/languages/java/org.eclipse.papyrus.designer.languages.java.jdt.texteditor/src/org/eclipse/papyrus/designer/languages/java/jdt/texteditor/sync/RevealCurrentOperation.java b/plugins/languages/java/org.eclipse.papyrus.designer.languages.java.jdt.texteditor/src/org/eclipse/papyrus/designer/languages/java/jdt/texteditor/sync/RevealCurrentOperation.java
new file mode 100644
index 0000000..26f6061
--- /dev/null
+++ b/plugins/languages/java/org.eclipse.papyrus.designer.languages.java.jdt.texteditor/src/org/eclipse/papyrus/designer/languages/java/jdt/texteditor/sync/RevealCurrentOperation.java
@@ -0,0 +1,119 @@
+/*******************************************************************************
+ * 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 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Ansgar Radermacher - ansgar.radermacher@cea.fr CEA LIST - initial API and implementation
+ *
+ *******************************************************************************/
+
+package org.eclipse.papyrus.designer.languages.java.jdt.texteditor.sync;
+
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IMethod;
+import org.eclipse.jdt.core.IParent;
+import org.eclipse.jdt.core.ISourceRange;
+import org.eclipse.jdt.core.ISourceReference;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jface.text.ITextSelection;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.uml2.uml.Classifier;
+import org.eclipse.uml2.uml.Element;
+
+
+public class RevealCurrentOperation {
+
+ public RevealCurrentOperation(IEditorInput input, Classifier classifier, String projectName) {
+ m_input = input;
+ m_classifier = classifier;
+ m_projectName = projectName;
+ }
+
+ public Element obtainSelectedElement(ITextSelection selection) {
+ IJavaElement ice = null; // CDTUITools.getEditorInputCElement(m_input);
+
+ if (ice instanceof ICompilationUnit) {
+// IJavaProject project = CoreModel.getDefault().getCModel().getCProject(m_projectName);
+//
+// IIndex index = null;
+// try {
+// index = CCorePlugin.getIndexManager().getIndex(project);
+// index.acquireReadLock();
+//
+// // index = CCorePlugin.getIndexManager().getIndex(project);
+// ICompilationUnit itu = (ICompilationUnit) ice;
+// // hack: force re-evaluation of AST node, requires modified CDT!
+// // Seems to be no longer required.
+// // ASTProvider.getASTProvider().fCache.setActiveElement(itu);
+//
+// IASTTranslationUnit ast = itu.getAST(index, ICompilationUnit.AST_SKIP_INDEXED_HEADERS);
+// IASTNodeSelector selector = ast.getNodeSelector(null);
+//
+// String opName = findOperation(itu, selector, itu, selection);
+// if (opName != null) {
+// int sep = opName.lastIndexOf("::"); //$NON-NLS-1$
+// if (sep != -1) {
+// opName = opName.substring(sep + 2);
+// }
+// Operation operation = m_classifier.getOperation(opName, null, null);
+// if (operation != null) {
+// return operation;
+// }
+// }
+//
+// } catch (CModelException e) {
+// Activator.getDefault().getLog().log(e.getStatus());
+// } catch (Exception e) {
+// System.err.println(e);
+// } finally {
+// if (index != null) {
+// index.releaseReadLock();
+// }
+// }
+ }
+ return m_classifier;
+ }
+
+ /**
+ * Examine the children of a translation unit in order to extract the methods that are defined within
+ * the unit
+ *
+ * @param icu
+ * @param selector
+ * @param parent
+ * @throws CModelException
+ */
+ public String findOperation(ICompilationUnit icu, IParent parent, ITextSelection selection) throws JavaModelException {
+
+ for (IJavaElement child : parent.getChildren()) {
+ if (child instanceof IParent) {
+ // return findOperation(icu, selector, (IParent) child, selection);
+ }
+ ISourceRange range = null;
+ if (child instanceof ISourceReference) {
+ range = ((ISourceReference) child).getSourceRange();
+ }
+ if (child instanceof IMethod) {
+ // function declaration is a superclass for method declaration (but need to trace functions differently?)
+ String name = ((IMethod) child).getElementName();
+ int pos = selection.getOffset();
+ if ((pos >= range.getOffset()) && (pos < range.getOffset() + range.getLength())) {
+ return name;
+ }
+ }
+ }
+ return null;
+ }
+
+ protected IEditorInput m_input;
+
+ protected Classifier m_classifier;
+
+ protected String m_projectName;
+}
diff --git a/plugins/languages/java/org.eclipse.papyrus.designer.languages.java.jdt.texteditor/src/org/eclipse/papyrus/designer/languages/java/jdt/texteditor/sync/SyncJDTtoModel.java b/plugins/languages/java/org.eclipse.papyrus.designer.languages.java.jdt.texteditor/src/org/eclipse/papyrus/designer/languages/java/jdt/texteditor/sync/SyncJDTtoModel.java
new file mode 100644
index 0000000..96753a1
--- /dev/null
+++ b/plugins/languages/java/org.eclipse.papyrus.designer.languages.java.jdt.texteditor/src/org/eclipse/papyrus/designer/languages/java/jdt/texteditor/sync/SyncJDTtoModel.java
@@ -0,0 +1,481 @@
+/*******************************************************************************
+ * Copyright (c) 2013 CEA LIST.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Ansgar Radermacher - ansgar.radermacher@cea.fr CEA LIST - initial API and implementation
+ *
+ *******************************************************************************/
+
+package org.eclipse.papyrus.designer.languages.java.jdt.texteditor.sync;
+
+import java.util.List;
+
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IImportDeclaration;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.ILocalVariable;
+import org.eclipse.jdt.core.IMethod;
+import org.eclipse.jdt.core.IParent;
+import org.eclipse.jdt.core.ISourceRange;
+import org.eclipse.jdt.core.ISourceReference;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jface.text.rules.IToken;
+import org.eclipse.papyrus.designer.languages.common.base.StringConstants;
+import org.eclipse.papyrus.designer.languages.common.extensionpoints.ILangCodegen;
+import org.eclipse.papyrus.designer.languages.common.extensionpoints.LanguageCodegen;
+import org.eclipse.papyrus.designer.languages.common.extensionpoints.SyncInformation;
+import org.eclipse.papyrus.designer.languages.java.jdt.texteditor.Activator;
+import org.eclipse.papyrus.designer.languages.java.jdt.texteditor.TextEditorConstants;
+import org.eclipse.papyrus.designer.languages.java.jdt.texteditor.Utils;
+import org.eclipse.papyrus.designer.languages.java.jdt.texteditor.listener.ModelListener;
+import org.eclipse.papyrus.designer.languages.java.profile.PapyrusJava.Array;
+import org.eclipse.papyrus.designer.languages.java.profile.PapyrusJava.Final;
+import org.eclipse.papyrus.designer.languages.java.profile.PapyrusJava.Import;
+import org.eclipse.papyrus.designer.transformation.base.utils.CommandSupport;
+import org.eclipse.papyrus.uml.tools.utils.StereotypeUtil;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.uml2.uml.Behavior;
+import org.eclipse.uml2.uml.BehavioralFeature;
+import org.eclipse.uml2.uml.Classifier;
+import org.eclipse.uml2.uml.Comment;
+import org.eclipse.uml2.uml.NamedElement;
+import org.eclipse.uml2.uml.Operation;
+import org.eclipse.uml2.uml.Parameter;
+import org.eclipse.uml2.uml.ParameterDirectionKind;
+import org.eclipse.uml2.uml.Type;
+
+public class SyncJDTtoModel implements Runnable {
+
+ // standard name used for return types
+ public static final String RET = "ret"; //$NON-NLS-1$
+
+ // special treatment of void in case of return parameters
+ public static final String VOID_TYPE = "void"; //$NON-NLS-1$
+
+ public static final String REGISTER = "register"; //$NON-NLS-1$
+
+ public static final String CONST = "const"; //$NON-NLS-1$
+
+ public static final String VOLATILE = "volatile"; //$NON-NLS-1$
+
+ public static final String sAtParam = "@param"; //$NON-NLS-1$
+
+ public static final String sAtReturn = "@return"; //$NON-NLS-1$
+
+ public static final String ansiCLib = "AnsiCLibrary"; //$NON-NLS-1$
+
+ public SyncJDTtoModel(IEditorInput input, Classifier classifier, String projectName, String generatorID) {
+ m_input = input;
+ m_classifier = classifier;
+ m_projectName = projectName;
+ m_codegen = LanguageCodegen.getGenerator(TextEditorConstants.JAVA, generatorID);
+ }
+
+
+ public final String c_cpp_langID = "C/C++"; //$NON-NLS-1$
+
+ public void syncCDTtoModel() {
+ CommandSupport.exec(m_classifier, "update model from CDT", this); //$NON-NLS-1$
+ }
+
+ @Override
+ public void run() {
+ IJavaElement ice = null; // CDTUITools.getEditorInputCElement(m_input);
+ ModelListener.syncFromEditor = true;
+
+ if (ice instanceof ICompilationUnit) {
+ ICompilationUnit icu = (ICompilationUnit) ice;
+
+ try {
+ examineChildren(icu, icu);
+ } catch (JavaModelException e) {
+ Activator.log.error(e);
+ }
+ }
+ ModelListener.syncFromEditor = false;
+ }
+
+ /**
+ * Examine the children of a translation unit in order to extract the
+ * methods that are defined within hte unit
+ *
+ * @param icu
+ * @param parent
+ * @throws JavaModelException
+ */
+ public void examineChildren(ICompilationUnit icu, IParent parent)
+ throws JavaModelException {
+
+ int position = 0;
+ // if (parent instanceof Namespace) {
+ for (IJavaElement child : parent.getChildren()) {
+ if (child instanceof IParent) {
+ examineChildren(icu, (IParent) child);
+ }
+ ISourceRange range = null;
+ if (child instanceof ISourceReference) {
+ range = ((ISourceReference) child).getSourceRange();
+ }
+ if (child instanceof IMethod) {
+ // function declaration is a superclass for method declaration
+ // (but need to trace functions differently?)
+ String name = ((IMethod) child).getElementName();
+ System.err.println("Name: " + name);
+ // IASTNode node = selector.findEnclosingNode(range.getStartPos(), range.getLength());
+ // if (node instanceof IASTFunctionDefinition) {
+ // IASTFunctionDefinition definition = (IASTFunctionDefinition) node;
+ // IASTFunctionDeclarator declarator = definition.getDeclarator();
+ // String unfilteredBody = getBody(icu, definition);
+ // // get additional information about method synchronization from generator
+ // SyncInformation syncInfo = m_codegen.getSyncInformation(name, unfilteredBody);
+ // String body = Utils.removeGenerated(unfilteredBody);
+ // if (syncInfo == null || !syncInfo.isGenerated) {
+ // // only update method, if it is not generated
+ // NamedElement ne = updateMethod(position, parent, name, body, declarator, syncInfo);
+ // updateComment(icu, definition, ne);
+ // }
+ // // System.err.println("body source <" + body + ">");
+ // }
+ position++;
+ }
+ }
+ }
+
+ /**
+ * update the contents of the CppInclude directive
+ *
+ * @param icu
+ * the translation unit
+ * @throws JavaModelException
+ */
+ public void updateJavaImport(ICompilationUnit icu) throws JavaModelException {
+ String body = StringConstants.EMPTY;
+
+ for (IImportDeclaration import_ : icu.getImports()) {
+ body += import_.getSource();
+ }
+ if (body.length() > 0) {
+ Import importSt = StereotypeUtil.applyApp(m_classifier, Import.class);
+ if (importSt != null) {
+ importSt.setManualImports(body);
+ }
+ }
+ }
+
+ /**
+ * Update a method in the model based on the qualified name.
+ *
+ * @param position
+ * The position of the method within the file. Used to identify
+ * renaming operations
+ * @param parent
+ * the CDT parent which is used to get a list of children
+ * @param qualifiedName
+ * the qualified name of a method
+ * @param body
+ * the method body
+ * @param declarator
+ * the declarator for the method
+ * @return the operation or the behavior within the model that got updated. The latter is returned in
+ * case of behaviors that do not have a specification (e.g. the effect of a transition).
+ */
+ public NamedElement updateMethod(int position, IMethod method, String qualifiedName, String body,
+ SyncInformation syncInfo) {
+
+ String names[] = qualifiedName.split(Utils.nsSep);
+ String name = names[names.length - 1];
+
+ Operation operation = null;
+ Behavior behavior = null;
+
+ return null;
+ }
+
+ /**
+ * Get a modifier that is next to a parameter variable
+ *
+ * @param token
+ * the token associated with a parameter
+ * @param modifiers
+ * a ParameterModifiers object (that gets modified)
+ */
+ protected void updateModifierFromParameter(IToken token, ParameterModifiers modifiers) {
+ // TODO
+ }
+
+ /**
+ * Update the multiplicity from an existing parameter
+ *
+ * @param parameter
+ * a new parameter (may be null)
+ * @param existingParameter
+ * an existing parameter (may be null)
+ */
+ protected void updateMultiplicity(Parameter parameter, Parameter existingParameter) {
+ if (parameter != null && existingParameter != null) {
+ parameter.setLower(existingParameter.getLower());
+ parameter.setUpper(existingParameter.getUpper());
+ }
+ }
+
+ /**
+ * Get a modifier that is next to a parameter type
+ *
+ * @param token
+ * the token associated with a parameter type
+ * @param modifiers
+ * a ParameterModifiers object (that gets modified)
+ * @return an eventually modified parameter type name
+ */
+ protected String updateModifierFromParameterType(IToken token, String parameterTypeName, ParameterModifiers modifiers) {
+ // TODO
+ return null;
+ }
+
+ /**
+ * Obtain the type of a parameter, checking (and loading) ANSI-C as well.
+ *
+ * @param parameterName
+ * @param typeName
+ * the name of a type (might be qualified, might be a simple type name)
+ * @param existingParameters
+ * @return
+ */
+ protected Type getParameterType(String typeName, Parameter existingParameter) {
+ return null;
+ }
+
+ /**
+ * @param paramList
+ * a list of parameters
+ * @param parameterName
+ * a parameter name
+ * @return the first parameter from the list with matching name. If the parameter
+ * name is null, return the first return parameter. returns null, if no
+ * matching name is found
+ */
+ protected Parameter getParameterViaName(List<Parameter> paramList, String parameterName) {
+ for (Parameter existingParameter : paramList) {
+ if (parameterName == null) {
+ if (existingParameter.getDirection() == ParameterDirectionKind.RETURN_LITERAL) {
+ return existingParameter;
+ }
+ } else if (existingParameter.getName().equals(parameterName)) {
+ return existingParameter;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Apply the modifiers for a parameter, notably the stereotypes of the C++ profile
+ *
+ * @param parameterType
+ * the CDT AST parameter specification
+ * @param umlParameter
+ * the UML parameter (to which a stereotype should be applied)
+ * @param modifiers
+ * the modifiers that should be applied (stored in an instance of class ParameterModifiers)
+ */
+ public void applyParameterModifiers(ILocalVariable parameter, Parameter umlParameter, ParameterModifiers modifiers) {
+ if (parameter.isReadOnly()) {
+ StereotypeUtil.apply(umlParameter, Final.class);
+ }
+
+ // only create array stereotype, if multiplicity == 1 (otherwise likely already handled by multiplicity)
+ if (umlParameter.getUpper() == 1 && false /* parameter.getArray.length() > 0 */) {
+ Array arraySt = StereotypeUtil.applyApp(umlParameter, Array.class);
+ if (arraySt != null && !modifiers.array.equals("[]") && (!modifiers.array.equals("[ ]"))) { //$NON-NLS-1$//$NON-NLS-2$
+ arraySt.setDefinition(modifiers.array);
+ }
+ }
+ }
+
+ /**
+ * Obtain an operation from the model by using the name of a CDT method.
+ * If an operation of the given name does not exist, it might indicate that
+ * the method has been renamed.
+ *
+ * @param name
+ * the operation name within CDT
+ * @param parent
+ * the parent of the CDT method within CDT editor model
+ * @param position
+ * the position within the other methods. This information is used to locate methods
+ * within the model that might have been renamed in the CDT editor.
+ * @return a UML operation
+ */
+ public Operation getModelOperationFromName(String name, IParent parent, int position) {
+ Operation operation = m_classifier.getOperation(name, null, null);
+
+ if (operation == null) {
+ // operation is not found via name in the model. try to locate the operation in the model at the same
+ // "position" as the method in the file and
+ // verify that this method does not have the same name as any method
+ // in the CDT file.
+ if (position < m_classifier.getOperations().size()) {
+ operation = m_classifier.getOperations().get(position);
+ String modelName = operation.getName();
+ try {
+ for (IJavaElement child : parent.getChildren()) {
+ if (child instanceof IMethod) {
+ String cdtName = ((IMethod) child).getElementName();
+ if (cdtName.equals(modelName)) {
+ // an existing operation in the CDT file already
+ // has this name
+ operation = null;
+ break;
+ }
+ }
+ }
+ } catch (JavaModelException e) {
+ }
+ }
+ }
+ return operation;
+ }
+
+ public static String getBody(ICompilationUnit icu, IMethod definition) throws JavaModelException {
+ String contents = definition.getSource();
+
+ // if (body instanceof IASTCompoundStatement) {
+ // IASTCompoundStatement bodyComp = (IASTCompoundStatement) body;
+
+ // IASTFileLocation bodyLoc = bodyComp.getFileLocation();
+ // int start = bodyLoc.getNodeOffset();
+ // int end = start + bodyLoc.getNodeLength();
+ // char contents[] = icu.getContents();
+ // body contains enclosing { } which we need to remove (+2, -2). We
+ // cannot use the
+ // first and last statement, since leading and trailing comments are
+ // not part of the AST tree.
+ // return Utils.decreaseIndent(contents, start + 2, end - 2);
+ // }
+ // return ""; //$NON-NLS-1$
+ return contents;
+ }
+
+ /**
+ * update a comment of a named element. Besides the comment of the element itself, comments on contained
+ * parameters are handled.
+ *
+ * @param icu
+ * a translation unit
+ * @param definition
+ * @param ne
+ * a named element that is either an operation or a behavior (in order to update parameters)
+ * @throws JavaModelException
+ */
+ public void updateComment(ICompilationUnit icu, IMethod method, NamedElement ne) throws JavaModelException {
+ String comment = method.getSource();
+ comment = comment.replace("\n * ", StringConstants.EOL).//$NON-NLS-1$
+ replace(StringConstants.COMMENT_END, StringConstants.EMPTY).trim();
+ if (comment.length() > 0) {
+ // filter @param
+ int atParam = comment.indexOf(sAtParam);
+ int atReturn = comment.indexOf(sAtReturn);
+ // does atReturn appear before @atParam?
+ int atParamOrReturn = (atReturn != -1 && (atReturn < atParam || atParam == -1)) ? atReturn : atParam;
+ String commentMethodOnly = (atParamOrReturn != -1) ? comment.substring(0, atParamOrReturn).trim() : comment;
+
+ while (atParam != -1) {
+ int currentAtParam = atParam;
+ atParam = comment.indexOf(sAtParam, atParam + 1);
+ String commentParam = (atParam != -1) ? comment.substring(currentAtParam, atParam)
+ : comment.substring(currentAtParam);
+ Comment commentParamUML;
+ int atParamName = sAtParam.length();
+
+ while ((atParamName < commentParam.length())
+ && Character.isWhitespace(commentParam.charAt(atParamName))) {
+ atParamName++;
+ }
+ int atParamNameEnd = atParamName;
+ while ((atParamNameEnd < commentParam.length())
+ && !Character.isWhitespace(commentParam.charAt(atParamNameEnd))) {
+ atParamNameEnd++;
+ }
+ if (atParamNameEnd < commentParam.length() - 1) {
+ String parameterName = commentParam.substring(atParamName, atParamNameEnd);
+ String commentParamText = commentParam.substring(atParamNameEnd).trim();
+ Parameter parameter = null;
+ if (ne instanceof BehavioralFeature) {
+ parameter = ((BehavioralFeature) ne).getOwnedParameter(parameterName, null, false, false);
+ } else if (ne instanceof Behavior) {
+ parameter = ((Behavior) ne).getOwnedParameter(parameterName, null, false, false);
+ }
+ if (parameter != null) {
+ EList<Comment> commentsParamUML = parameter.getOwnedComments();
+ if (commentsParamUML.size() == 0) {
+ commentParamUML = parameter.createOwnedComment();
+ commentParamUML.getAnnotatedElements().add(commentParamUML);
+ } else {
+ commentParamUML = commentsParamUML.get(0);
+ }
+ commentParamUML.setBody(commentParamText);
+ } else {
+ // parameter is not found in model, e.g. either renamed
+ // or not yet existing
+ // store comment in operation comment
+ commentMethodOnly += "\n " + sAtParam + parameterName + //$NON-NLS-1$
+ " not found(!) " + commentParamText; //$NON-NLS-1$
+ }
+ }
+ }
+ if (commentMethodOnly.equals(StringConstants.STAR)) {
+ commentMethodOnly = StringConstants.EMPTY;
+ }
+ // update/create comment, if a non-empty comment context has been detected.
+ EList<Comment> commentsUML = ne.getOwnedComments();
+ if (commentMethodOnly.length() > 0) {
+ Comment commentUML;
+ if (commentsUML.size() == 0) {
+ commentUML = ne.createOwnedComment();
+ commentUML.getAnnotatedElements().add(commentUML);
+ } else {
+ commentUML = commentsUML.get(0);
+ }
+ commentUML.setBody(commentMethodOnly);
+ } else if (commentsUML.size() > 0) {
+ // destroy first comment
+ commentsUML.get(0).destroy();
+ }
+ }
+ }
+
+ /**
+ * Accessor
+ *
+ * @return value of codegen attribute
+ */
+ public ILangCodegen getCodeGen() {
+ return m_codegen;
+ }
+
+ /**
+ * input of the CDT editor. Used to obtain code within editor.
+ */
+ protected IEditorInput m_input;
+
+ /**
+ * The classifier (class) that is currently edited
+ */
+ protected Classifier m_classifier;
+
+ /**
+ * name of CDT project in which the generated code is stored.
+ */
+ protected String m_projectName;
+
+ /**
+ * reference to code generator
+ */
+ protected ILangCodegen m_codegen;
+}
diff --git a/plugins/languages/java/org.eclipse.papyrus.designer.languages.java.jdt.texteditor/src/org/eclipse/papyrus/designer/languages/java/jdt/texteditor/sync/SyncModelToJDT.java b/plugins/languages/java/org.eclipse.papyrus.designer.languages.java.jdt.texteditor/src/org/eclipse/papyrus/designer/languages/java/jdt/texteditor/sync/SyncModelToJDT.java
new file mode 100644
index 0000000..8514f5a
--- /dev/null
+++ b/plugins/languages/java/org.eclipse.papyrus.designer.languages.java.jdt.texteditor/src/org/eclipse/papyrus/designer/languages/java/jdt/texteditor/sync/SyncModelToJDT.java
@@ -0,0 +1,80 @@
+/*******************************************************************************
+ * Copyright (c) 2013 CEA LIST.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Ansgar Radermacher - ansgar.radermacher@cea.fr CEA LIST - initial API and implementation
+ *
+ *******************************************************************************/
+
+package org.eclipse.papyrus.designer.languages.java.jdt.texteditor.sync;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.papyrus.designer.languages.common.base.StringConstants;
+import org.eclipse.papyrus.designer.languages.common.extensionpoints.ILangCodegen;
+import org.eclipse.papyrus.designer.languages.common.extensionpoints.LanguageCodegen;
+import org.eclipse.papyrus.designer.languages.java.jdt.texteditor.TextEditorConstants;
+import org.eclipse.papyrus.infra.core.Activator;
+import org.eclipse.uml2.uml.Classifier;
+
+/**
+ * Main listener for model changes (registered via plugin.xml). It will delegate
+ * to the sub-listeners for specific sub-elements (type, operation, port, ...) that
+ * can be found in this package
+ *
+ */
+public class SyncModelToJDT {
+
+ /**
+ * set to true, if a synchronization from an CDT editor to the model is active
+ */
+ public static boolean syncFromEditor;
+
+ public static IFile syncModelToCDT(Classifier classifier, String generatorID) {
+ if ((classifier == null) || (classifier.eResource() == null)) {
+ return null;
+ }
+
+ ILangCodegen codegen = LanguageCodegen.getGenerator(TextEditorConstants.JAVA, generatorID);
+
+ // don't create target project, if not existing yet (as listener would start generating
+ // code unexpectedly
+ IProject modelProject = codegen.getTargetProject(classifier, false);
+ if (modelProject == null) {
+ return null;
+ }
+
+ IContainer srcPkg = null;
+ IFile javaFile = null;
+ try {
+ codegen.generateCode(modelProject, classifier, null); // need listener for sync in both directions!
+
+ String suffix = "java"; //$NON-NLS-1$
+
+ javaFile = modelProject.getFile(new Path("src-gen/" + codegen.getFileName(modelProject, classifier) + StringConstants.DOT + suffix));
+
+ // IStorage storage = new TextStorage(string);
+ } finally {
+ // Refresh the container for the newly created files. This needs to be done even
+ // during error because of the possibility for partial results.
+ try {
+ if (srcPkg != null) {
+ srcPkg.refreshLocal(IResource.DEPTH_INFINITE, null);
+ }
+ } catch (CoreException e) {
+ Activator.log.error(e);
+ }
+ }
+ return javaFile;
+ }
+}