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; + } +}