Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoraradermache2013-03-27 05:30:52 -0400
committeraradermache2013-03-27 05:30:52 -0400
commita755a83cbc051ebfa1bd76484aa7b653cb22693b (patch)
tree3e134f4103086b375676b4cc90a2fccda91555cc /extraplugins/codegen/org.eclipse.papyrus.cpp.codegen/src
parent88f3acfc96d85f80a0d938bb09cda3bd9498fc60 (diff)
downloadorg.eclipse.papyrus-a755a83cbc051ebfa1bd76484aa7b653cb22693b.tar.gz
org.eclipse.papyrus-a755a83cbc051ebfa1bd76484aa7b653cb22693b.tar.xz
org.eclipse.papyrus-a755a83cbc051ebfa1bd76484aa7b653cb22693b.zip
May contain code-generation plugs-in that are independent of C++
Diffstat (limited to 'extraplugins/codegen/org.eclipse.papyrus.cpp.codegen/src')
-rw-r--r--extraplugins/codegen/org.eclipse.papyrus.cpp.codegen/src/org/eclipse/papyrus/cpp/codegen/Activator.java65
-rw-r--r--extraplugins/codegen/org.eclipse.papyrus.cpp.codegen/src/org/eclipse/papyrus/cpp/codegen/Constants.java36
-rw-r--r--extraplugins/codegen/org.eclipse.papyrus.cpp.codegen/src/org/eclipse/papyrus/cpp/codegen/StdStereo.java46
-rw-r--r--extraplugins/codegen/org.eclipse.papyrus.cpp.codegen/src/org/eclipse/papyrus/cpp/codegen/preferences/CppCodeGenConstants.java31
-rw-r--r--extraplugins/codegen/org.eclipse.papyrus.cpp.codegen/src/org/eclipse/papyrus/cpp/codegen/preferences/CppCodeGenPreferenceInitializer.java36
-rw-r--r--extraplugins/codegen/org.eclipse.papyrus.cpp.codegen/src/org/eclipse/papyrus/cpp/codegen/preferences/CppCodeGenUtils.java48
-rw-r--r--extraplugins/codegen/org.eclipse.papyrus.cpp.codegen/src/org/eclipse/papyrus/cpp/codegen/transformation/ModelElementsCreator.java420
-rw-r--r--extraplugins/codegen/org.eclipse.papyrus.cpp.codegen/src/org/eclipse/papyrus/cpp/codegen/utils/ClassUtils.java164
-rw-r--r--extraplugins/codegen/org.eclipse.papyrus.cpp.codegen/src/org/eclipse/papyrus/cpp/codegen/utils/GenUtils.java765
-rw-r--r--extraplugins/codegen/org.eclipse.papyrus.cpp.codegen/src/org/eclipse/papyrus/cpp/codegen/utils/Modifier.java74
10 files changed, 1685 insertions, 0 deletions
diff --git a/extraplugins/codegen/org.eclipse.papyrus.cpp.codegen/src/org/eclipse/papyrus/cpp/codegen/Activator.java b/extraplugins/codegen/org.eclipse.papyrus.cpp.codegen/src/org/eclipse/papyrus/cpp/codegen/Activator.java
new file mode 100644
index 00000000000..83cc1860acf
--- /dev/null
+++ b/extraplugins/codegen/org.eclipse.papyrus.cpp.codegen/src/org/eclipse/papyrus/cpp/codegen/Activator.java
@@ -0,0 +1,65 @@
+/*******************************************************************************
+ * Copyright (c) 2006 - 2012 CEA LIST.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * CEA LIST - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.papyrus.cpp.codegen;
+
+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.cpp.codegen"; //$NON-NLS-1$
+
+ // The shared instance
+ private static Activator plugin;
+
+ /**
+ * Returns the shared instance
+ *
+ * @return the shared instance
+ */
+ public static Activator getDefault() {
+ return plugin;
+ }
+
+ /**
+ * The constructor
+ */
+ public Activator() {
+ plugin = this;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
+ */
+ @Override
+ public void start(BundleContext context) throws Exception {
+ super.start(context);
+ }
+
+ /*
+ * (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);
+ }
+
+}
diff --git a/extraplugins/codegen/org.eclipse.papyrus.cpp.codegen/src/org/eclipse/papyrus/cpp/codegen/Constants.java b/extraplugins/codegen/org.eclipse.papyrus.cpp.codegen/src/org/eclipse/papyrus/cpp/codegen/Constants.java
new file mode 100644
index 00000000000..33e044a0323
--- /dev/null
+++ b/extraplugins/codegen/org.eclipse.papyrus.cpp.codegen/src/org/eclipse/papyrus/cpp/codegen/Constants.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2006 - 2012 CEA LIST.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * CEA LIST - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.papyrus.cpp.codegen;
+
+/**
+ * String constants for the code generation
+ *
+ * @author ansgar
+ *
+ */
+public class Constants {
+
+ public static final String includeHFile = "// include associated header file";
+
+ public static final String cppIncPreBodyStart = "// Include from CppInclude stereotype (pre-body)";
+
+ public static final String cppIncPreBodyEnd = "// End of CppInclude stereotype (pre-body)";
+
+ public static final String cppIncBodyStart = "// Include from CppInclude declaration (body)";
+
+ public static final String cppIncBodyEnd = "// End of CppInclude stereotype (body)";
+
+ public static final String derivedIncludes = "// Derived includes directives";
+
+ public static final String forwardDecl = "// forward declarations";
+
+ public static final String staticAttributes = "// static attributes (if any)";
+}
diff --git a/extraplugins/codegen/org.eclipse.papyrus.cpp.codegen/src/org/eclipse/papyrus/cpp/codegen/StdStereo.java b/extraplugins/codegen/org.eclipse.papyrus.cpp.codegen/src/org/eclipse/papyrus/cpp/codegen/StdStereo.java
new file mode 100644
index 00000000000..b27a63cd525
--- /dev/null
+++ b/extraplugins/codegen/org.eclipse.papyrus.cpp.codegen/src/org/eclipse/papyrus/cpp/codegen/StdStereo.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright (c) 2006 - 2012 CEA LIST.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * CEA LIST - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.papyrus.cpp.codegen;
+
+import org.eclipse.papyrus.cpp.codegen.utils.GenUtils;
+import org.eclipse.uml2.uml.Element;
+
+public class StdStereo {
+
+ public final static String create = "Create";
+
+ public final static String destroy = "Destroy";
+
+ /**
+ * In the UML 2.4 plugin, the Standard profile is split into an L2 and an L3 profile
+ */
+ public final static String[] namespaces = { "Standard", "StandardProfileL2" };
+
+ /**
+ * Check whether a stereotype of the standard profile is applied
+ *
+ * @param element
+ * The element to check
+ * @param stdName
+ * the non qualified name of a stereotype within the standard
+ * profile
+ * @return
+ */
+ public static boolean isApplied(Element element, String stdName) {
+ for(String namespace : namespaces) {
+ if(GenUtils.hasStereotype(element, namespace + "::" + stdName)) {
+ return true;
+ }
+ }
+ return false;
+ }
+}
diff --git a/extraplugins/codegen/org.eclipse.papyrus.cpp.codegen/src/org/eclipse/papyrus/cpp/codegen/preferences/CppCodeGenConstants.java b/extraplugins/codegen/org.eclipse.papyrus.cpp.codegen/src/org/eclipse/papyrus/cpp/codegen/preferences/CppCodeGenConstants.java
new file mode 100644
index 00000000000..3e579c05b10
--- /dev/null
+++ b/extraplugins/codegen/org.eclipse.papyrus.cpp.codegen/src/org/eclipse/papyrus/cpp/codegen/preferences/CppCodeGenConstants.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * Copyright (c) 2006 - 2012 CEA LIST.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * CEA LIST - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.papyrus.cpp.codegen.preferences;
+
+public class CppCodeGenConstants {
+
+ /**
+ * Suffix for generated header files
+ */
+ public static final String P_HEADER_SUFFIX = "headSuffix";
+
+ /**
+ * Suffix for generated body/implementation files
+ */
+ public static final String P_IMPLEM_SUFFIX = "implSuffix";
+
+ /**
+ * User defined comment header in generated files
+ */
+ public static final String P_COMMENT_HEADER = "commentHeader";
+
+}
diff --git a/extraplugins/codegen/org.eclipse.papyrus.cpp.codegen/src/org/eclipse/papyrus/cpp/codegen/preferences/CppCodeGenPreferenceInitializer.java b/extraplugins/codegen/org.eclipse.papyrus.cpp.codegen/src/org/eclipse/papyrus/cpp/codegen/preferences/CppCodeGenPreferenceInitializer.java
new file mode 100644
index 00000000000..96cacb33444
--- /dev/null
+++ b/extraplugins/codegen/org.eclipse.papyrus.cpp.codegen/src/org/eclipse/papyrus/cpp/codegen/preferences/CppCodeGenPreferenceInitializer.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2006 - 2012 CEA LIST.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * CEA LIST - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.papyrus.cpp.codegen.preferences;
+
+import org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.papyrus.cpp.codegen.Activator;
+
+
+public class CppCodeGenPreferenceInitializer extends AbstractPreferenceInitializer {
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer#initializeDefaultPreferences()
+ */
+ public void initializeDefaultPreferences() {
+ IPreferenceStore store = Activator.getDefault().getPreferenceStore();
+ store.setDefault(CppCodeGenConstants.P_HEADER_SUFFIX, "h");
+ store.setDefault(CppCodeGenConstants.P_IMPLEM_SUFFIX, "cpp");
+
+ // Default value for P_COMMENT_HEADER
+ String NL = System.getProperties().getProperty("line.separator");
+ String defaultValue = "" + "// --------------------------------------------------------" + NL + "// Code generated by Papyrus C++" + NL + "// --------------------------------------------------------" + NL + NL;
+ store.setDefault(CppCodeGenConstants.P_COMMENT_HEADER, defaultValue);
+ }
+}
diff --git a/extraplugins/codegen/org.eclipse.papyrus.cpp.codegen/src/org/eclipse/papyrus/cpp/codegen/preferences/CppCodeGenUtils.java b/extraplugins/codegen/org.eclipse.papyrus.cpp.codegen/src/org/eclipse/papyrus/cpp/codegen/preferences/CppCodeGenUtils.java
new file mode 100644
index 00000000000..d7094ee9786
--- /dev/null
+++ b/extraplugins/codegen/org.eclipse.papyrus.cpp.codegen/src/org/eclipse/papyrus/cpp/codegen/preferences/CppCodeGenUtils.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright (c) 2006 - 2012 CEA LIST.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * CEA LIST - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.papyrus.cpp.codegen.preferences;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.papyrus.cpp.codegen.Activator;
+
+/**
+ * Utility class that returns the preference values
+ *
+ * @author ansgar
+ *
+ */
+public class CppCodeGenUtils {
+
+ protected static IPreferenceStore preferenceStore = null;
+
+ public static String getHeaderSuffix() {
+ initPreferenceStore();
+ return preferenceStore.getString(CppCodeGenConstants.P_HEADER_SUFFIX);
+ }
+
+ public static String getBodySuffix() {
+ initPreferenceStore();
+ return preferenceStore.getString(CppCodeGenConstants.P_IMPLEM_SUFFIX);
+ }
+
+ public static String getCommentHeader() {
+ initPreferenceStore();
+ return preferenceStore.getString(CppCodeGenConstants.P_COMMENT_HEADER);
+ }
+
+ public static void initPreferenceStore() {
+ if(preferenceStore == null) {
+ preferenceStore = Activator.getDefault().getPreferenceStore();
+ }
+ }
+
+}
diff --git a/extraplugins/codegen/org.eclipse.papyrus.cpp.codegen/src/org/eclipse/papyrus/cpp/codegen/transformation/ModelElementsCreator.java b/extraplugins/codegen/org.eclipse.papyrus.cpp.codegen/src/org/eclipse/papyrus/cpp/codegen/transformation/ModelElementsCreator.java
new file mode 100644
index 00000000000..85b2c514068
--- /dev/null
+++ b/extraplugins/codegen/org.eclipse.papyrus.cpp.codegen/src/org/eclipse/papyrus/cpp/codegen/transformation/ModelElementsCreator.java
@@ -0,0 +1,420 @@
+/*******************************************************************************
+ * Copyright (c) 2006 - 2012 CEA LIST.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * CEA LIST - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.papyrus.cpp.codegen.transformation;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.URI;
+
+import org.eclipse.core.filesystem.EFS;
+import org.eclipse.core.filesystem.IFileStore;
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.papyrus.cpp.codegen.jet.CppBindBody;
+import org.eclipse.papyrus.cpp.codegen.jet.CppBindHeader;
+import org.eclipse.papyrus.cpp.codegen.jet.CppClassBody;
+import org.eclipse.papyrus.cpp.codegen.jet.CppClassHeader;
+import org.eclipse.papyrus.cpp.codegen.jet.CppInterfaceHeader;
+import org.eclipse.papyrus.cpp.codegen.jet.CppPackageHeader;
+import org.eclipse.papyrus.cpp.codegen.jet.CppTemplateHeader;
+import org.eclipse.papyrus.cpp.codegen.jet.util.CppClassIncludeDeclaration;
+import org.eclipse.papyrus.cpp.codegen.utils.GenUtils;
+import org.eclipse.papyrus.cpp.profile.StUtils;
+import org.eclipse.uml2.uml.Class;
+import org.eclipse.uml2.uml.Classifier;
+import org.eclipse.uml2.uml.DataType;
+import org.eclipse.uml2.uml.Enumeration;
+import org.eclipse.uml2.uml.Interface;
+import org.eclipse.uml2.uml.NamedElement;
+import org.eclipse.uml2.uml.Namespace;
+import org.eclipse.uml2.uml.Package;
+import org.eclipse.uml2.uml.PackageableElement;
+import org.eclipse.uml2.uml.PrimitiveType;
+import org.eclipse.uml2.uml.Relationship;
+import org.eclipse.uml2.uml.Usage;
+
+import Cpp.CppExternClass;
+import Cpp.CppInclude;
+import Cpp.CppNoCodeGen;
+import Cpp.CppRoot;
+import Cpp.CppTemplate;
+import Cpp.ManualGeneration;
+
+
+
+/**
+ * Main class of code generator
+ */
+public class ModelElementsCreator {
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param project
+ * the project in which the generated code should be placed
+ * @param hppExt
+ * The file suffix for c++ header files
+ * @param cppExt
+ * The file suffix for c++ implementation files
+ * @param headerComment
+ * Prefix for each generated file
+ */
+ public ModelElementsCreator(IProject project, String hppExt, String cppExt, String headerComment) {
+ this.hppExt = hppExt;
+ this.cppExt = cppExt;
+ this.headerComment = headerComment;
+ this.project = project;
+ }
+
+ private String hppExt;
+
+ private String cppExt;
+
+ private String headerComment;
+
+ private IProject project;
+
+ /**
+ * Main function for user calls. Creates code for a packageable element.
+ *
+ * @param monitor
+ * a progress monitor
+ * @param element
+ * the element for which code should be generated
+ * @throws CoreException
+ */
+ public void createPackageableElement(IProgressMonitor monitor, PackageableElement element) throws CoreException {
+ IContainer packageContainer = getContainer(element);
+ createPackageableElement(packageContainer, monitor, element);
+ }
+
+ /**
+ * Variant of main function: user may supply explicit container (also used by internal function to avoid
+ * re-calculating the entry container for each element).
+ *
+ * @param packageContainer
+ * The container (directory), in which code should be created
+ * @param monitor
+ * a progress monitor
+ * @param element
+ * the element for which code should be generated
+ * @throws CoreException
+ */
+ public void createPackageableElement(IContainer packageContainer, IProgressMonitor monitor, PackageableElement element) throws CoreException {
+ if(element instanceof Package) {
+ createPackage(packageContainer, monitor, (Package)element);
+ } else if(element instanceof Class) {
+ createClassFiles(packageContainer, (Class)element);
+ } else if(element instanceof Interface) {
+ createInterfaceFile(packageContainer, (Interface)element);
+ } else if((element instanceof PrimitiveType) || (element instanceof Enumeration) || (element instanceof Usage)) {
+ // do nothing, included in package
+ } else if(element instanceof DataType) {
+ createDataTypeFiles(packageContainer, (DataType)element);
+ } else if(element instanceof Relationship) {
+ // no code generation for relationships
+ } else {
+ System.err.println("C++ code generator: unsupported model element " + element);
+ }
+ }
+
+ public void removePackageableElement(IProgressMonitor monitor, PackageableElement element) throws CoreException {
+ IContainer packageContainer = getContainer(element);
+ if(packageContainer instanceof IFolder) {
+ if(element instanceof Package) {
+ IFolder folder = ((IFolder)packageContainer).getFolder(element.getName());
+ folder.delete(true, null);
+ } else if(element instanceof Classifier) {
+ IFile file = ((IFolder)packageContainer).getFile(element.getName());
+ file.delete(true, null);
+ }
+ }
+ }
+
+ /**
+ * Creates the files corresponding to the class. For a "simple" class
+ * generates 2 headers (one for the privates concrete operations and one for
+ * the attributes, public operations and virtual / abstract operations and
+ * one body file.
+ *
+ * @param folder
+ * @param classObject
+ * @throws CoreException
+ */
+ protected void createClassFiles(IContainer container, Class classObject) throws CoreException {
+
+ // treat case of manual code generation
+ if(GenUtils.hasStereotype(classObject, ManualGeneration.class)) {
+ ManualGeneration mg = StUtils.getApplication(classObject, ManualGeneration.class);
+ CppInclude cppInclude = StUtils.getApplication(classObject, CppInclude.class);
+ String fileContent = headerComment + cppInclude.getHeader();
+ createFile(container, classObject.getName() + "." + hppExt, fileContent, true);
+
+ CppClassIncludeDeclaration jetIDecl = new CppClassIncludeDeclaration();
+ String include = jetIDecl.generate(classObject);
+
+ fileContent = headerComment + cppInclude.getPreBody() + GenUtils.NL + include + GenUtils.NL + cppInclude.getBody();
+ String ext = GenUtils.maskNull(mg.getExtensionBody());
+ if(ext.length() == 0) {
+ ext = cppExt;
+ }
+ createFile(container, classObject.getName() + "." + ext, fileContent, true);
+ }
+
+ // Only generate when no CppNoCodeGen stereotype is applied to the class
+ else if((!GenUtils.hasStereotype(classObject, CppNoCodeGen.class)) && (!GenUtils.hasStereotype(classObject, CppExternClass.class)) && (!GenUtils.hasStereotype(classObject, CppTemplate.class))) {
+
+ CppClassHeader headerGenerator = new CppClassHeader();
+ CppClassBody bodyGenerator = new CppClassBody();
+
+ // Template Bound Class
+ if(GenUtils.isTemplateBoundElement(classObject)) {
+ CppBindHeader templateBindingGenerator = new CppBindHeader();
+ CppBindBody bodyBindingGenerator = new CppBindBody();
+ String fileContent = headerComment + templateBindingGenerator.generate(classObject);
+ createFile(container, classObject.getName() + "." + hppExt, fileContent, true);
+
+ fileContent = headerComment + bodyBindingGenerator.generate(classObject);
+ createFile(container, classObject.getName() + "." + cppExt, fileContent, true);
+ } else {
+ if(classObject.isTemplate()) {
+ CppTemplateHeader templateGenerator = new CppTemplateHeader();
+ String fileContent = headerComment + templateGenerator.generate(classObject);
+ createFile(container, classObject.getName() + "." + hppExt, fileContent, true);
+ } else {
+
+ // The class is actually a class.
+
+ // Header file generation
+ String fileContent = headerComment + headerGenerator.generate(classObject);
+ createFile(container, classObject.getName() + "." + hppExt, fileContent, true);
+
+ // "Traditional" code generation : one body file for all
+ // operations.
+ fileContent = headerComment + bodyGenerator.generate(classObject);
+ createFile(container, classObject.getName() + "." + cppExt, fileContent, true);
+ }
+ }
+ }
+ }
+
+ /**
+ * Creates the files corresponding to data types.
+ *
+ * @param container
+ * @param dataTypeObject
+ * @throws CoreException
+ */
+ protected void createDataTypeFiles(IContainer container, DataType dataTypeObject) throws CoreException {
+
+ CppClassHeader headerGenerator = new CppClassHeader();
+ CppClassBody bodyGenerator = new CppClassBody();
+
+ String fileContent = "";
+
+ // Only generate when no CppNoCodeGen stereotype is applied to the class
+ if((!GenUtils.hasStereotype(dataTypeObject, CppNoCodeGen.class)) && (!GenUtils.hasStereotype(dataTypeObject, CppExternClass.class)) && (!GenUtils.hasStereotype(dataTypeObject, CppTemplate.class))) {
+
+ // Template Bound Class
+ // templates for data types currently not supported
+ /*
+ * if(dataTypeObject.isTemplateBoundElement())
+ * {
+ * CppBindHeader templateBindingGenerator = new CppBindHeader();
+ * CppBindBody bodyBindingGenerator = new CppBindBody();
+ * fileContent = headerComment
+ * + templateBindingGenerator.generate(dataTypeObject);
+ * createFile(container, dataTypeObject.getName() + "." + hpp,
+ * fileContent, true);
+ *
+ * fileContent = headerComment
+ * + bodyBindingGenerator.generate(dataTypeObject);
+ * createFile(container, dataTypeObject.getName() + "." + cpp,
+ * fileContent, true);
+ * } else {
+ */
+
+ // Header file generation
+ fileContent = headerComment + headerGenerator.generate(dataTypeObject);
+ createFile(container, dataTypeObject.getName() + "." + hppExt, fileContent, true);
+
+ // "Traditional" code generation : one body file for all
+ // operations.
+ fileContent = headerComment + bodyGenerator.generate(dataTypeObject);
+ createFile(container, dataTypeObject.getName() + "." + cppExt, fileContent, true);
+ }
+ }
+
+ /**
+ * Creates a <em>text</em> file in an eclipse container (either IFolder or
+ * IProject). If this file already exists it is replaced.
+ *
+ * @param owner
+ * the container that will contain the file.
+ * @param filename
+ * The name of the file to create.
+ * @param content
+ * Te text content of the file.
+ * @throws CoreException
+ */
+ protected void createFile(IContainer owner, String filename, String content, boolean force) throws CoreException {
+ IFile file = null;
+ if(owner instanceof IProject) {
+ file = ((IProject)owner).getFile(filename);
+ } else if(owner instanceof IFolder) {
+ file = ((IFolder)owner).getFile(filename);
+ } else {
+ // undefined
+ }
+ if(file != null) {
+ createFile(file, content, force);
+ }
+ }
+
+ /**
+ * Creates a <em>text</em> file in an eclipse folder. If this file already
+ * exists it is replaced.
+ *
+ * @param folder
+ * The folder that will contain the file.
+ * @param filename
+ * The name of the file to create.
+ * @param content
+ * Te text content of the file.
+ * @throws CoreException
+ */
+ protected void createFile(IFile file, String content, boolean force) throws CoreException {
+ if(file.exists() && force) {
+ // file.delete(true,true,null);
+ // YT - deleting files produce inconsistency in SVN working copies
+ final URI locationURI = file.getLocationURI();
+ if(locationURI != null) {
+ IFileStore store = EFS.getStore(locationURI);
+ OutputStream os = store.openOutputStream(0, null);
+ try {
+ os.write(content.getBytes());
+ } catch (IOException e) {
+ System.err.println(e);
+ }
+ }
+ // file.setContents(new ByteArrayInputStream(content.getBytes()),
+ // true, true, null);
+ } else if(file.exists() && !(force)) {
+ // the file is not updated
+ } else {
+ // the file does not exists
+ file.create(new ByteArrayInputStream(content.getBytes()), true, null);
+ }
+ }
+
+ /**
+ * Creates the header file corresponding to the interface
+ *
+ * @param folder
+ * @param interfaceObject
+ * @throws CoreException
+ */
+ protected void createInterfaceFile(IContainer container, Interface interfaceObject) throws CoreException {
+ if(!GenUtils.hasStereotype(interfaceObject, CppNoCodeGen.class)) {
+
+ CppInterfaceHeader headerGenerator = new CppInterfaceHeader();
+ String fileContent = "";
+
+ fileContent = headerComment + headerGenerator.generate(interfaceObject);
+ createFile(container, interfaceObject.getName() + "." + hppExt, fileContent, true);
+ }
+ }
+
+ /**
+ * Recursively creates folders for a given package
+ *
+ * @param packageContainer
+ * The folder where the folder hierarchy for this package will be
+ * created.
+ * @param monitor
+ * a progress monitor
+ * @param pkg
+ * the package for which code should be created
+ * @throws CoreException
+ */
+ protected void createPackage(IContainer packageContainer, IProgressMonitor monitor, Package pkg) throws CoreException {
+ monitor.subTask("generate package " + pkg.getQualifiedName());
+
+ if(!GenUtils.hasStereotype(pkg, CppRoot.class) && !GenUtils.hasStereotype(pkg, CppNoCodeGen.class)) {
+
+ String fileContent = "";
+
+ packageContainer = (packageContainer instanceof IProject) ? ((IProject)packageContainer).getFolder(pkg.getName()) : ((IFolder)packageContainer).getFolder(pkg.getName());
+
+ // Create a new folder corresponding to the package if it does not exist
+ if(!packageContainer.exists()) {
+ // if packageContainer is a Project, it necessarily exists
+ ((IFolder)packageContainer).create(false, true, null);
+ }
+
+ // Creates the header for the package.
+ CppPackageHeader pkgHeaderGenerator = new CppPackageHeader();
+ fileContent = "";
+ fileContent = headerComment + pkgHeaderGenerator.generate(pkg);
+ createFile(packageContainer, "Pkg_" + pkg.getName() + "." + hppExt, fileContent, true);
+
+ // Continue generation parsing package content
+ // If CppNoCodeGen on package, it applies to its content
+
+ for(PackageableElement currentElement : pkg.getPackagedElements()) {
+ createPackageableElement(packageContainer, monitor, currentElement);
+ }
+ }
+ }
+
+ /**
+ * Return a container (folder) for a given named element. The folder is embedded into a set
+ * of folders that correspond to the namespaces of the element. These folders will be
+ * created, if the do not exist (comparable to "mkdir -p" in Unix).
+ *
+ * @param element
+ * a named element
+ * @return folder for this element
+ */
+ public IContainer getContainer(NamedElement element) {
+ try {
+ IContainer packageContainer = project;
+ EList<Namespace> namespaces = element.allNamespaces();
+ for(int i = namespaces.size() - 1; i >= 0; i--) {
+ Namespace ns = namespaces.get(i);
+ if(GenUtils.hasStereotype(ns, CppRoot.class)) {
+ // TODO: not very clean. Is this stereotype still used?
+ packageContainer = project;
+ } else if(packageContainer instanceof IFolder) {
+ packageContainer = ((IFolder)packageContainer).getFolder(ns.getName());
+ } else if(packageContainer instanceof IProject) {
+ packageContainer = ((IProject)packageContainer).getFolder(ns.getName());
+ }
+ if(!packageContainer.exists()) {
+ // if packageContainer is a Project, it necessarily exists
+ ((IFolder)packageContainer).create(false, true, null);
+ }
+ }
+ return packageContainer;
+ } catch (CoreException e) {
+ e.printStackTrace();
+ return null;
+ }
+ }
+}
diff --git a/extraplugins/codegen/org.eclipse.papyrus.cpp.codegen/src/org/eclipse/papyrus/cpp/codegen/utils/ClassUtils.java b/extraplugins/codegen/org.eclipse.papyrus.cpp.codegen/src/org/eclipse/papyrus/cpp/codegen/utils/ClassUtils.java
new file mode 100644
index 00000000000..78957b9bccd
--- /dev/null
+++ b/extraplugins/codegen/org.eclipse.papyrus.cpp.codegen/src/org/eclipse/papyrus/cpp/codegen/utils/ClassUtils.java
@@ -0,0 +1,164 @@
+/*******************************************************************************
+ * Copyright (c) 2006 - 2012 CEA LIST.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * CEA LIST - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.papyrus.cpp.codegen.utils;
+
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.common.util.UniqueEList;
+import org.eclipse.papyrus.cpp.codegen.Constants;
+import org.eclipse.papyrus.cpp.codegen.jet.util.CppClassIncludeDeclaration;
+import org.eclipse.papyrus.cpp.codegen.jet.util.CppOwnerPackageIncludeDeclaration;
+import org.eclipse.papyrus.cpp.codegen.jet.util.CppStaticAttributeImplementation;
+import org.eclipse.uml2.uml.Classifier;
+import org.eclipse.uml2.uml.Enumeration;
+import org.eclipse.uml2.uml.Package;
+import org.eclipse.uml2.uml.PrimitiveType;
+import org.eclipse.uml2.uml.Property;
+
+import Cpp.CppConst;
+import Cpp.CppExternClass;
+import Cpp.CppInclude;
+import Cpp.CppNoCodeGen;
+
+/**
+ * A set of utility functions related to classes.
+ *
+ * @author ansgar (ansgar.radermacher@cea.fr)
+ *
+ */
+public class ClassUtils {
+
+ /**
+ * Generate the "pre-body" statements that are stored in the CppInclude stereotype
+ * "pre" means: add before the ".cpp" file includes its own header file of a program
+ *
+ * @param currentClass
+ * @return generated text
+ */
+ public static String getCppIncludePreBody(Classifier currentClass) {
+ CppInclude cppInclude = GenUtils.getApplication(currentClass, CppInclude.class);
+ if(cppInclude != null) {
+ return GenUtils.addNL(cppInclude.getPreBody());
+ }
+ return "";
+ }
+
+ /**
+ * Generate the body statements that are stored in the CppInclude stereotype
+ * Body means that these statements are added at the beginning of the "body" (the ".cpp") file.
+ *
+ * @param currentClass
+ * @return generated text
+ */
+ public static String getCppIncludeBody(Classifier currentClass) {
+ CppInclude cppInclude = GenUtils.getApplication(currentClass, CppInclude.class);
+ if(cppInclude != null) {
+ return GenUtils.addNL(cppInclude.getBody());
+ }
+ return "";
+ }
+
+ /**
+ * Generated include statements related to dependencies.
+ *
+ * @param currentCl
+ * @return generated text
+ */
+ public static String createIncludeDecl(Classifier currentCl) {
+ EList<Classifier> depClassifiers = GenUtils.getDependencies(currentCl);
+ return createIncludeDecl(depClassifiers, currentCl);
+ }
+
+ public static String createIncludeDecl(EList<Classifier> usedClassifiers, Classifier currentCl) {
+ String includes = "";
+ String forwardDecls = Constants.forwardDecl;
+
+ // avoid duplicates
+ EList<Package> ownerPackages = new UniqueEList<Package>();
+
+ for(Classifier cl : usedClassifiers) {
+
+ // Only add include if this is not for the current class
+ if(!currentCl.equals(cl)) {
+ // ... and if it does not have the stereotype "CppNoCodeGen", unless
+ // it has stereotype "CppExternalClass"
+ if((!GenUtils.hasStereotype(cl, CppNoCodeGen.class)) || GenUtils.hasStereotype(cl, CppExternClass.class)) {
+ String newInclude = "";
+
+ if((cl instanceof Enumeration) || (cl instanceof PrimitiveType)) {
+ // Enumeration is not defined in a separate file, but in the
+ // package that owns it => include the owning package (might be a duplicate input, if owning
+ // package is also the owner of current class)
+ if(cl.getOwner() instanceof Package) {
+ Package owner = (Package)cl.getOwner();
+ if(!ownerPackages.contains(owner)) {
+ ownerPackages.add(owner);
+ CppOwnerPackageIncludeDeclaration jetIDecl = new CppOwnerPackageIncludeDeclaration();
+ newInclude = jetIDecl.generate(owner);
+ }
+ }
+ } else {
+ // include the file associated with the classifier
+ CppClassIncludeDeclaration jetIDecl = new CppClassIncludeDeclaration();
+ newInclude = jetIDecl.generate(cl);
+ }
+
+ includes = includes + newInclude;
+
+ // generate a forward declaration
+ // this is useful, even if the ".h" file associated with the class is included:
+ // in case of cyclic dependencies, the include file may actually not be included since
+ // its #ifndef rule will exclude code.
+ // Don't generate forward for external classes, which may actually be non-classes
+ /*
+ * if ((cl instanceof Class) && !GenUtils.hasStereotype(cl, CppdxternClass)) {
+ * Class classWithoutBinding = (Class) cl;
+ * if (classWithoutBinding.getTemplateBindings().isEmpty()) {
+ * CppClassIncludeClassDeclaration jetCDecl
+ * = new CppClassIncludeClassDeclaration();
+ * String newClass = jetCDecl.generate(classWithoutBinding);
+ * forwardDecls += newClass;
+ * }
+ * }
+ */
+ }
+ }
+ }
+ includes += forwardDecls;
+ return includes;
+ }
+
+ /**
+ * get the list of static attributes for the implementation
+ *
+ * @param currentClass
+ * @return
+ */
+ public static String getStaticAttributes(Classifier currentClass) {
+ String attrSDecl = "";
+
+ CppStaticAttributeImplementation jetSAttDecl = new CppStaticAttributeImplementation();
+
+ for(Property attribute : currentClass.getAttributes()) {
+
+ // check that the attribute is not a static const, in that case it is declared and defined in the header file
+
+ // Static and not constant (constant static attributes are declared within the class declaration)
+ if(attribute.isStatic() && !GenUtils.hasStereotype(attribute, CppConst.class)) {
+ attrSDecl = attrSDecl + jetSAttDecl.generate(attribute);
+ }
+ }
+ if(attrSDecl.length() > 0) {
+ attrSDecl = Constants.staticAttributes + "\n" + attrSDecl;
+ }
+ return attrSDecl;
+ }
+}
diff --git a/extraplugins/codegen/org.eclipse.papyrus.cpp.codegen/src/org/eclipse/papyrus/cpp/codegen/utils/GenUtils.java b/extraplugins/codegen/org.eclipse.papyrus.cpp.codegen/src/org/eclipse/papyrus/cpp/codegen/utils/GenUtils.java
new file mode 100644
index 00000000000..1c7977bd166
--- /dev/null
+++ b/extraplugins/codegen/org.eclipse.papyrus.cpp.codegen/src/org/eclipse/papyrus/cpp/codegen/utils/GenUtils.java
@@ -0,0 +1,765 @@
+/*******************************************************************************
+ * Copyright (c) 2006 - 2012 CEA LIST.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * CEA LIST - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.papyrus.cpp.codegen.utils;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+
+import org.eclipse.emf.common.util.BasicEList;
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.common.util.UniqueEList;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.uml2.uml.AggregationKind;
+import org.eclipse.uml2.uml.Behavior;
+import org.eclipse.uml2.uml.Class;
+import org.eclipse.uml2.uml.Classifier;
+import org.eclipse.uml2.uml.ClassifierTemplateParameter;
+import org.eclipse.uml2.uml.Comment;
+import org.eclipse.uml2.uml.ConnectableElementTemplateParameter;
+import org.eclipse.uml2.uml.Dependency;
+import org.eclipse.uml2.uml.DirectedRelationship;
+import org.eclipse.uml2.uml.Element;
+import org.eclipse.uml2.uml.Interface;
+import org.eclipse.uml2.uml.LiteralBoolean;
+import org.eclipse.uml2.uml.LiteralInteger;
+import org.eclipse.uml2.uml.LiteralString;
+import org.eclipse.uml2.uml.LiteralUnlimitedNatural;
+import org.eclipse.uml2.uml.NamedElement;
+import org.eclipse.uml2.uml.Namespace;
+import org.eclipse.uml2.uml.OpaqueBehavior;
+import org.eclipse.uml2.uml.Operation;
+import org.eclipse.uml2.uml.OperationTemplateParameter;
+import org.eclipse.uml2.uml.Package;
+import org.eclipse.uml2.uml.Parameter;
+import org.eclipse.uml2.uml.ParameterableElement;
+import org.eclipse.uml2.uml.PrimitiveType;
+import org.eclipse.uml2.uml.Property;
+import org.eclipse.uml2.uml.Stereotype;
+import org.eclipse.uml2.uml.TemplateBinding;
+import org.eclipse.uml2.uml.TemplateParameter;
+import org.eclipse.uml2.uml.TemplateSignature;
+import org.eclipse.uml2.uml.Type;
+
+import Cpp.CppExternClass;
+import Cpp.CppNoCodeGen;
+import Cpp.CppType;
+import Cpp.CppVisibility;
+
+
+
+/**
+ * Some utilities: a set of static method for C++ code generator
+ * Mainly "Template" related methods
+ * Should probably be put in com.cea.utils in next release
+ *
+ * @author wassim
+ *
+ */
+public class GenUtils {
+
+ public static final String NL = System.getProperties().getProperty("line.separator");
+
+ /**
+ * Retrieve template bindings for the class passed as a Parameter
+ * only one template binding can exist for an element
+ *
+ * @param current
+ * Class on which the template binding is searched
+ * @return the template binding of current Class
+ */
+ public static TemplateBinding getTemplateBindings(Class current) {
+ TemplateBinding binding = null;
+ if(current.getTemplateBindings().size() == 1) {
+ binding = current.getTemplateBindings().get(0);
+ }
+
+ return binding;
+ }
+
+ public static boolean isTemplateBoundElement(Class uml2Class) {
+ boolean result = false;
+ EList<TemplateBinding> tb = uml2Class.getTemplateBindings();
+ if(tb != null) {
+ Iterator<TemplateBinding> itb = tb.iterator();
+ while(itb.hasNext()) {
+ TemplateBinding currentTb = itb.next();
+ result = currentTb.getBoundElement() == uml2Class;
+ }
+ }
+ return result;
+ }
+
+ public static Collection<TemplateParameter> getTemplateParameters(Classifier classifier) {
+
+ Collection<TemplateParameter> params = new ArrayList<TemplateParameter>();
+ TemplateSignature ts = classifier.getOwnedTemplateSignature();
+ if(ts != null) {
+ params.addAll(ts.getOwnedParameters());
+ }
+
+ return params;
+ }
+
+ public static Collection<ParameterableElement> getTemplateParameteredElements(Classifier classifier) {
+
+ Collection<ParameterableElement> params = new ArrayList<ParameterableElement>();
+ TemplateSignature ts = classifier.getOwnedTemplateSignature();
+ if(ts != null) {
+ for(TemplateParameter tp : ts.getOwnedParameters()) {
+ if(tp != null) {
+ params.add(tp.getParameteredElement());
+ }
+ }
+ }
+
+ return params;
+ }
+
+ /**
+ * Return a list of template parameters without type
+ *
+ * @param classifier
+ * @return
+ */
+ public static String getTemplateParametersWoType(Classifier classifier) {
+ String tparamWoType = "";
+
+ Iterator<TemplateParameter> it = GenUtils.getTemplateParameters(classifier).iterator();
+
+ while(it.hasNext()) {
+ TemplateParameter currentTParam = it.next();
+ tparamWoType = tparamWoType + GenUtils.getName(currentTParam);
+
+ if(it.hasNext()) {
+ tparamWoType = tparamWoType + ", ";
+ }
+ }
+ return tparamWoType;
+ }
+
+ /**
+ * The standard UML and MARTE libraries do not apply the cppType stereotype. Yet, we want to treat these
+ * types in an identical way, i.e. we use a typedef to the associated primitive C++ type
+ *
+ * @param type
+ * @return
+ */
+ public static String getStdtypes(PrimitiveType type) {
+ Object owner = type.getOwner();
+ String owningPkgName = "";
+ if(owner instanceof Package) {
+ owningPkgName = ((Package)owner).getName();
+ }
+ if(owningPkgName.equals("PrimitiveTypes") || // used in UML 2.4
+ owningPkgName.equals("UMLPrimitiveTypes") || // used in UML < 2.4
+ owningPkgName.equals("MARTE_PrimitivesTypes")) {
+ String td = null;
+ String name = type.getName();
+
+ if(name.equals("Boolean")) {
+ td = "bool";
+ } else if(name.equals("Integer")) {
+ td = "int";
+ } else if(name.equals("String")) {
+ td = "const char *";
+ } else if(name.equals("Unlimited Natural")) {
+ td = "unsigned long";
+ }
+ if(td != null) {
+ return "typedef " + td + " " + name + ";";
+ }
+ // else unknown within UMLPrimitiveTypes, treat in standard way
+ }
+
+ return "";
+ }
+
+ /**
+ * Gives the type of the parameter or null for void.
+ * (used in particular in the context of template parameters
+ * TODO: redundant with qualifiedName??)
+ *
+ * @return the template type formated as string
+ */
+ public static String getType(TemplateParameter templateParam) {
+ String type = "", name = "";
+
+ // Retrieve name of the ParameteredElement (when possible = it is a NamedElement
+ ParameterableElement pElt = templateParam.getParameteredElement();
+ if((pElt != null) && (pElt instanceof NamedElement)) {
+ name = ((NamedElement)pElt).getName();
+ if(templateParam instanceof ClassifierTemplateParameter) {
+ type = "class";
+ } else if(templateParam instanceof OperationTemplateParameter) {
+ type = "";
+ } else if(templateParam instanceof ConnectableElementTemplateParameter) {
+ type = "";
+ } else {// uml2TemplateParameter instanceof TemplateParameter
+ if(pElt instanceof LiteralInteger) {
+ type = "int";
+ } else if(pElt instanceof LiteralString) {
+ type = "String";
+ } else if(pElt instanceof LiteralBoolean) {
+ type = "Boolean";
+ } else if(pElt instanceof LiteralUnlimitedNatural) {
+ type = "UnlimitedNatural";
+ } else {
+ type = pElt.eClass().getName();
+ }
+ }
+ } else {
+ name = "undefined";
+ }
+
+ // Retrieve the name of the type
+ /*
+ * if (templateParam instanceof ClassifierTemplateParameter) {
+ * type = "class";
+ * } else
+ * {
+ * if ((pElt != null) && (pElt instanceof LiteralInteger)) {
+ * type = "int";
+ * } else {
+ * // Need test the other cases (LiteralBoolean ? LiteralString ?)
+ * type = "undefined";
+ * }
+ * }
+ */
+
+ return (type + " " + name);
+ }
+
+ public static String getName(TemplateParameter templateParam) {
+ String name = "";
+ ParameterableElement pElt = templateParam.getParameteredElement();
+ if((pElt != null) && (pElt instanceof NamedElement)) {
+ name = ((NamedElement)pElt).getName();
+ } else {
+ name = "undefined";
+ }
+
+ return name;
+ }
+
+ /**
+ * Retrieve a list of types that belong to by a classifier in the current class
+ *
+ * @param current
+ * Class on which the attributes are searched
+ * @return collection of classes which are the type of the attributes
+ */
+ public static EList<Classifier> getOwnedAttributeTypes(Classifier current) {
+ EList<Classifier> result = new UniqueEList<Classifier>();
+
+ Iterator<Property> attributes;
+ attributes = current.getAttributes().iterator();
+ while(attributes.hasNext()) {
+ Property currentAttribute = attributes.next();
+ Type type = currentAttribute.getType();
+ if(type instanceof Classifier) {
+ Classifier attrType = (Classifier)type;
+ result.add(attrType);
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Retrieve the operations in the current class then for each
+ * operation it finds the parameters that have a class type
+ *
+ * @param current
+ * Class on which the attributes are searched
+ * @return collection of classes which are the types of the operations parameters
+ */
+ public static EList<Classifier> getIncludesFromOperations(Classifier current) {
+ EList<Classifier> result = new UniqueEList<Classifier>();
+ Iterator<Operation> operations = current.getOperations().iterator();
+ while(operations.hasNext()) {
+ Operation op = operations.next();
+ Iterator<Parameter> i = op.getOwnedParameters().iterator();
+ while(i.hasNext()) {
+ Parameter param = i.next();
+ Type type = param.getType();
+ if(type instanceof Classifier) {
+ Classifier paramType = (Classifier)type;
+ result.add(paramType);
+ }
+ }
+ }
+ return result;
+ }
+
+ public static EList<Interface> getImplementedInterfaces(Class current) {
+ EList<Interface> interfaces = new UniqueEList<Interface>();
+ Iterator<Interface> interfacesIt = current.getImplementedInterfaces().iterator();
+ Interface currentInterface;
+ while(interfacesIt.hasNext()) {
+ currentInterface = (Interface)interfacesIt.next();
+ interfaces.add(currentInterface);
+ }
+ return interfaces;
+ }
+
+ /**
+ * Return a list of classifiers that are referenced by relationships, i.e.
+ * dependencies or associations
+ *
+ * @param current
+ * @return
+ */
+ public static EList<Classifier> getRelationships(Classifier current) {
+ EList<Classifier> classifiers = new UniqueEList<Classifier>();
+
+ for(DirectedRelationship relationship : current.getSourceDirectedRelationships()) {
+
+ if(relationship.getTargets().size() > 0) {
+ // there should always be at least one element in the target
+ // list and it should be a classifier, but better check.
+ Element element = relationship.getTargets().get(0);
+ if(element instanceof Classifier) {
+ classifiers.add((Classifier)element);
+ }
+ }
+ }
+ return classifiers;
+ }
+
+ /**
+ * Return a list of classifiers that are referenced via dependencies
+ *
+ * @param current
+ * @return
+ */
+ public static EList<Classifier> getDependencies(Classifier current) {
+ EList<Classifier> classifiers = new UniqueEList<Classifier>();
+
+ for(DirectedRelationship relationship : current.getSourceDirectedRelationships()) {
+ if(relationship instanceof Dependency) {
+ if(relationship.getTargets().size() > 0) {
+ // there should always be at least one element in the target
+ // list and it should be a classifier, but better check.
+ Element element = relationship.getTargets().get(0);
+ if(element instanceof Classifier) {
+ classifiers.add((Classifier)element);
+ }
+ }
+ }
+ }
+ return classifiers;
+ }
+
+ /**
+ * Return a list of classifiers that are referenced via all kinds of relations except
+ * dependencies
+ *
+ * @param current
+ * @return
+ */
+ public static EList<Classifier> getRelationshipsNoDeps(Classifier current) {
+ EList<Classifier> classifiers = new UniqueEList<Classifier>();
+
+ for(DirectedRelationship relationship : current.getSourceDirectedRelationships()) {
+ if(!(relationship instanceof Dependency)) {
+ if(relationship.getTargets().size() > 0) {
+ // there should always be at least one element in the target
+ // list and it should be a classifier, but better check.
+ Element element = relationship.getTargets().get(0);
+ if(element instanceof Classifier) {
+ classifiers.add((Classifier)element);
+ }
+ }
+ }
+ }
+ return classifiers;
+ }
+
+ /**
+ * Return the qualified name of a named element, but use "_" instead of "::" as separator
+ *
+ * @param ne
+ * a named element
+ * @return the fully qualified name with "_" as separator character
+ */
+ public static String getFullName(NamedElement ne) {
+ return ne.getQualifiedName().replace("::", "_");
+ }
+
+ /**
+ * return the full name in upper case
+ *
+ * @param ne
+ * @return
+ */
+ public static String getFullNameUC(NamedElement ne) {
+ return ne.getQualifiedName().replace("::", "_").toUpperCase();
+ }
+
+ /**
+ * Return a C++ namespace definition for a named element
+ *
+ * @param ne
+ * a named element
+ * @return a C++ namespace definition for a named element
+ */
+ public static String getNamespace(NamedElement ne) {
+ String namespace = "";
+ for(Namespace ns : ne.allNamespaces()) {
+ if(ns.getOwner() != null) {
+ String nsName = ns.getName();
+ if(!namespace.equals("")) {
+ nsName += "::";
+ }
+ namespace = nsName + namespace;
+ }
+ }
+ if(!namespace.equals("")) {
+ namespace = "\n" + "using namespace " + namespace + ";\n";
+ }
+ return namespace;
+ }
+
+ /**
+ * Return a C++ open-namespace definition for a named element
+ *
+ * @param ne
+ * a named element
+ * @return a C++ open-namespace definition for a named element
+ */
+ public static String openNS(NamedElement ne) {
+ String openNS = "";
+ currentNS = ne.getNamespace();
+ for(Namespace ns : ne.allNamespaces()) {
+ if(ns.getOwner() != null) {
+ openNS = "namespace " + ns.getName() + " {\n" + openNS;
+ }
+ }
+ return openNS;
+ }
+
+ /**
+ * Return a C++ close-namespace definition for a named element
+ *
+ * @param ne
+ * a named element
+ * @return a C++ close-namespace definition for a named element
+ */
+ public static String closeNS(NamedElement ne) {
+ String closeNS = "";
+ for(Namespace ns : ne.allNamespaces()) {
+ if(ns.getOwner() != null) {
+ closeNS += "} // of namespace " + ns.getName() + "\n";
+ }
+ }
+ return closeNS;
+ }
+
+ public static String qualifiedName(NamedElement ne) {
+ Object owner = ne.getOwner();
+ String owningPkgName = "";
+ if(owner instanceof Package) {
+ owningPkgName = ((Package)owner).getName();
+ }
+ if((hasStereotype(ne, CppExternClass.class)) || (hasStereotype(ne, CppNoCodeGen.class))) {
+ return ne.getName();
+ } else if(owningPkgName.equals("AnsiCLibrary")) {
+ // always use the short name for types within the ANSI C library
+ return ne.getName();
+ }
+
+ String qName = ne.getName();
+ if(currentNS == ne.getNamespace()) {
+ // return simple name, if in current namespace
+ return qName;
+ }
+ if(ne instanceof PrimitiveType) {
+ if(!hasStereotype(ne, CppType.class) && (getStdtypes((PrimitiveType)ne).length() == 0)) {
+ // is a primitive type without further definition and not a standard primitive type
+ // => assume that it is a external type without namespace
+ return qName;
+ }
+ }
+
+ for(Namespace ns : ne.allNamespaces()) {
+ // don't add top-level
+ if(ns.getOwner() != null) {
+ qName = ns.getName() + "::" + qName;
+ }
+ }
+ if(qName.contains("::")) {
+ // is a qualified name => make path absolute
+ return "::" + qName;
+ } else {
+ return qName;
+ }
+ }
+
+ public static String getComments(Element element) {
+ String commentText = "";
+ for(Comment comment : element.getOwnedComments()) {
+ commentText += comment.getBody();
+ }
+ return commentText;
+ }
+
+ /**
+ * Return a list of dependent package (the list of dependent
+ * elements filtered for packages)
+ *
+ * @param pkg
+ * @return
+ */
+ public static EList<Package> getUsedPackages(Package pkg) {
+ EList<Package> result = new BasicEList<Package>();
+ for(Element depElement : pkg.getClientDependencies()) {
+ if(depElement instanceof Package) {
+ result.add((Package)depElement);
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Return a list of dependent classes (the list of dependent
+ * elements filtered for classes)
+ *
+ * @param pkg
+ * @return
+ */
+ public static EList<Classifier> getUsedClassifiers(Classifier cls) {
+ EList<Classifier> result = new BasicEList<Classifier>();
+ for(Element depElement : cls.getClientDependencies()) {
+ if(depElement instanceof Classifier) {
+ result.add((Classifier)depElement);
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Return the qualified name of a package, but use "/" instead of "::" as separator
+ *
+ * @param pkg
+ * @return
+ */
+ public static String getFullPath(Package pkg) {
+ return pkg.getQualifiedName().replace("::", "/");
+ }
+
+ /**
+ * Is a certain stereotype applied?
+ *
+ * @param element
+ * @param stereotype
+ * fully qualified stereotype name
+ * @return
+ */
+ public static boolean hasStereotype(Element element, String stereotName) {
+ EList<Stereotype> list = element.getAppliedStereotypes();
+ return element.getAppliedStereotype(stereotName) != null;
+ }
+
+ /**
+ * Is a certain stereotype applied?
+ *
+ * @param element
+ * @param stereotype
+ * fully qualified stereotype name
+ * @return
+ */
+ public static boolean hasStereotype(Element element, java.lang.Class<? extends EObject> clazz) {
+ for(EObject stereoApplication : element.getStereotypeApplications()) {
+ // check whether the stereotype is a subclass of the passed parameter clazz
+ if(clazz.isAssignableFrom(stereoApplication.getClass())) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Return the stereotype application by passing an element of the static profile
+ *
+ * @param element
+ * the UML model element
+ * @param clazz
+ * the class of an element of a static profile. Compatible sub-types will be returned as well
+ * @return the stereotype application or null
+ */
+ @SuppressWarnings("unchecked")
+ public static <T extends EObject> T getApplication(Element element, java.lang.Class<T> clazz) {
+ for(EObject stereoApplication : element.getStereotypeApplications()) {
+ // check whether the stereotype is an instance of the passed parameter clazz
+ if(clazz.isInstance(stereoApplication)) {
+ return (T)stereoApplication;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Is a certain stereotype applied?
+ *
+ * @param element
+ * @param stereotype
+ * fully qualified stereotype name
+ * @return
+ */
+ public static void setStereotype(Element element, String stereotName, boolean apply) {
+ Stereotype stereotype = element.getApplicableStereotype(stereotName);
+ if(stereotype != null) {
+ if(apply) {
+ if(!element.isStereotypeApplied(stereotype)) {
+ element.applyStereotype(stereotype);
+ }
+ } else {
+ if(element.isStereotypeApplied(stereotype)) {
+ element.unapplyStereotype(stereotype);
+ }
+ }
+ }
+ }
+
+ /**
+ * This method returns the stereotype applied to a certain element when given its name.
+ * Returns null, if a stereotype of that name does not exist.
+ * This function is quite similar to getAppliedStereotype, the difference is that it
+ * is not based on fully qualified name.
+ */
+ public static String getTaggedValue(Element element, String stereo_name, String attrib_name) {
+ Stereotype stereotype = element.getAppliedStereotype(stereo_name);
+ if(stereotype == null) {
+ return "";
+ }
+ Object value = element.getValue(stereotype, attrib_name);
+ if(value == null) {
+ return "";
+ }
+
+ if(value instanceof NamedElement) {
+ return ((NamedElement)value).getName();
+ } else if(value instanceof String) {
+ return (String)value;
+ } else {
+ return value.toString();
+ }
+ }
+
+ /**
+ * This method returns the stereotype applied to a certain element when given its name.
+ * Returns null, if a stereotype of that name does not exist.
+ * This function is quite similar to getAppliedStereotype, the difference is that it
+ * is not based on fully qualified name.
+ */
+ public static void setTaggedValue(Element element, String stereo_name, String attrib_name, Object value) {
+ Stereotype stereotype = element.getAppliedStereotype(stereo_name);
+ if(stereotype != null) {
+ element.setValue(stereotype, attrib_name, value);
+ }
+ }
+
+ /**
+ * @param operation
+ * the operation
+ * @param selectedLanguage
+ * the selected language
+ * @return Return the first body of a selected language that is provided by
+ * one of the operation's methods
+ */
+ public static String getBody(Operation operation, String selectedLanguage) {
+ for(Behavior behavior : operation.getMethods()) {
+ if(behavior instanceof OpaqueBehavior) {
+ OpaqueBehavior ob = (OpaqueBehavior)behavior;
+ Iterator<String> bodies = ob.getBodies().iterator();
+ for(String language : ob.getLanguages()) {
+ String body = bodies.next();
+ if(language.equals(selectedLanguage)) {
+ return indent(body, "\t");
+ }
+ }
+ }
+ }
+ return "";
+ }
+
+ /**
+ * Format text output, indent each line with the passed string
+ *
+ * @param source
+ * @param indentStr
+ * @return
+ */
+ public static String indent(String source, String indentStr) {
+ String result = "";
+ String[] lines = source.split("\n");
+ for(int i = 0; i < lines.length; i++) {
+ result += indentStr + lines[i];
+ if(i < lines.length - 1) {
+ result += "\n";
+ }
+ }
+ return result;
+ }
+
+ /**
+ * return true, if shared aggregation (no composition).
+ * TODO: consider whether used as association?
+ *
+ * @param p
+ * @return
+ */
+ public static boolean isAggregation(Property p) {
+ return /* (p.getAssociation() != null) && */
+ (p.getAggregation() == AggregationKind.SHARED_LITERAL);
+ }
+
+ public static String getVisibility(Element element) {
+ // get visibility and target name
+ CppVisibility cppVisibility = GenUtils.getApplication(element, CppVisibility.class);
+ if(cppVisibility != null) {
+ return cppVisibility.getValue();
+ } else {
+ return "public";
+ }
+ }
+
+ /**
+ * Avoid null strings, i.e. replace null strings by empty strings
+ *
+ * @param str
+ * @return
+ */
+ public static String maskNull(String str) {
+ if(str == null) {
+ return "";
+ }
+ return str;
+ }
+
+ /**
+ * Add a newline character, unless the string is empty and unless it already ends with a
+ * newline character
+ */
+ public static String addNL(String str) {
+ if(str == null || str.length() == 0) {
+ return "";
+ }
+ if(str.endsWith(NL)) {
+ return str;
+ } else {
+ return str + NL;
+ }
+ }
+
+ private static Namespace currentNS;
+}
diff --git a/extraplugins/codegen/org.eclipse.papyrus.cpp.codegen/src/org/eclipse/papyrus/cpp/codegen/utils/Modifier.java b/extraplugins/codegen/org.eclipse.papyrus.cpp.codegen/src/org/eclipse/papyrus/cpp/codegen/utils/Modifier.java
new file mode 100644
index 00000000000..1f0c96d8bc0
--- /dev/null
+++ b/extraplugins/codegen/org.eclipse.papyrus.cpp.codegen/src/org/eclipse/papyrus/cpp/codegen/utils/Modifier.java
@@ -0,0 +1,74 @@
+/*******************************************************************************
+ * Copyright (c) 2006 - 2012 CEA LIST.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * CEA LIST - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.papyrus.cpp.codegen.utils;
+
+import org.eclipse.uml2.uml.Element;
+
+import Cpp.CppArray;
+import Cpp.CppConst;
+import Cpp.CppPtr;
+import Cpp.CppRef;
+
+/**
+ * Utility functions managing the "modifier" of an element, i.e. additional information whether a passed
+ * parameter or an attribute is a pointer, a reference, an array or constant.
+ *
+ * @author ansgar
+ *
+ */
+public class Modifier {
+
+ public String ptr;
+
+ public String ref;
+
+ public String array;
+
+ public String isConst;
+
+ public Modifier() {
+ ptr = "";
+ ref = "";
+ array = "";
+ isConst = "";
+ }
+
+ /**
+ * Create instance and initialize the ptr/ref/array/isConst attributes.
+ *
+ * @param currentParameter
+ */
+ public Modifier(Element currentParameter) {
+
+ // Pointer
+ CppPtr cppPtr = GenUtils.getApplication(currentParameter, CppPtr.class);
+ if(cppPtr != null) {
+ ptr = (cppPtr.getDeclaration() != null) ? cppPtr.getDeclaration() : "*";
+ } else {
+ ptr = "";
+ }
+
+ // Ref
+ ref = GenUtils.hasStereotype(currentParameter, CppRef.class) ? "&" : "";
+
+ // Array
+ CppArray cppArray = GenUtils.getApplication(currentParameter, CppArray.class);
+ if(cppArray != null) {
+ array = (cppArray.getDefinition() != null) ? cppArray.getDefinition() : "[]";
+ } else {
+ array = "";
+ }
+
+ // Const
+ isConst = GenUtils.hasStereotype(currentParameter, CppConst.class) ? "const " : "";
+ }
+}

Back to the top