diff --git a/moclodash/fr.inria.diverse.cloning.external-libs/.classpath b/moclodash/fr.inria.diverse.cloning.external-libs/.classpath
new file mode 100644
index 0000000000000000000000000000000000000000..a6f7254100cef44362d7906a2a763ad22205b0db
--- /dev/null
+++ b/moclodash/fr.inria.diverse.cloning.external-libs/.classpath
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/moclodash/fr.inria.diverse.cloning.external-libs/.gitignore b/moclodash/fr.inria.diverse.cloning.external-libs/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..5e56e040ec0902e58df8573adaec65c5da6e9304
--- /dev/null
+++ b/moclodash/fr.inria.diverse.cloning.external-libs/.gitignore
@@ -0,0 +1 @@
+/bin
diff --git a/moclodash/fr.inria.diverse.cloning.external-libs/.project b/moclodash/fr.inria.diverse.cloning.external-libs/.project
new file mode 100644
index 0000000000000000000000000000000000000000..40be714cc430de7a3a061cd8a207b053e7c8ad31
--- /dev/null
+++ b/moclodash/fr.inria.diverse.cloning.external-libs/.project
@@ -0,0 +1,28 @@
+
+
+ fr.inria.diverse.cloning.external-libs
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ org.eclipse.pde.ManifestBuilder
+
+
+
+
+ org.eclipse.pde.SchemaBuilder
+
+
+
+
+
+ org.eclipse.pde.PluginNature
+ org.eclipse.jdt.core.javanature
+
+
diff --git a/moclodash/fr.inria.diverse.cloning.external-libs/.settings/org.eclipse.jdt.core.prefs b/moclodash/fr.inria.diverse.cloning.external-libs/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..f42de363afaae68bbd968318f1d331877f5514fc
--- /dev/null
+++ b/moclodash/fr.inria.diverse.cloning.external-libs/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,7 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
+org.eclipse.jdt.core.compiler.compliance=1.7
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.7
diff --git a/moclodash/fr.inria.diverse.cloning.external-libs/META-INF/MANIFEST.MF b/moclodash/fr.inria.diverse.cloning.external-libs/META-INF/MANIFEST.MF
new file mode 100644
index 0000000000000000000000000000000000000000..c119376212b3d8d0e1a0e1c5d3e10499f852fe49
--- /dev/null
+++ b/moclodash/fr.inria.diverse.cloning.external-libs/META-INF/MANIFEST.MF
@@ -0,0 +1,14 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: External-libs
+Bundle-SymbolicName: fr.inria.diverse.cloning.external-libs
+Bundle-Version: 0.1.0.qualifier
+Bundle-RequiredExecutionEnvironment: JavaSE-1.7
+Bundle-ClassPath: .,
+ lib/commons-io-1.4.jar,
+ lib/jopt-simple-4.6.jar,
+ lib/slf4j-api-1.6.6.jar,
+ lib/slf4j-jdk14-1.6.6.jar,
+ lib/zt-zip-1.7.jar
+Export-Package: joptsimple,
+ org.zeroturnaround.zip
diff --git a/moclodash/fr.inria.diverse.cloning.external-libs/build.properties b/moclodash/fr.inria.diverse.cloning.external-libs/build.properties
new file mode 100644
index 0000000000000000000000000000000000000000..4d92724042eaf9fdc48fa8a8ed192e4f69c44c6a
--- /dev/null
+++ b/moclodash/fr.inria.diverse.cloning.external-libs/build.properties
@@ -0,0 +1,9 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ lib/commons-io-1.4.jar,\
+ lib/jopt-simple-4.6.jar,\
+ lib/slf4j-api-1.6.6.jar,\
+ lib/slf4j-jdk14-1.6.6.jar,\
+ lib/zt-zip-1.7.jar
diff --git a/moclodash/fr.inria.diverse.cloning.external-libs/pom.xml b/moclodash/fr.inria.diverse.cloning.external-libs/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..214d19c0da28dad3b178efd489a209fa2012f208
--- /dev/null
+++ b/moclodash/fr.inria.diverse.cloning.external-libs/pom.xml
@@ -0,0 +1,123 @@
+
+
+
+ 4.0.0
+ fr.inria.diverse.cloning
+ fr.inria.diverse.cloning.external-libs
+ 0.1.0-SNAPSHOT
+ eclipse-plugin
+
+
+ fr.inria.diverse.cloning
+ moclodash
+ 0.1.0-SNAPSHOT
+
+
+
+
+ org.zeroturnaround
+ zt-zip
+ 1.7
+ jar
+ compile
+
+
+ net.sf.jopt-simple
+ jopt-simple
+ 4.6
+ jar
+ compile
+
+
+ org.slf4j
+ slf4j-jdk14
+ 1.6.6
+ jar
+ compile
+
+
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+
+ maven-dependency-plugin
+
+
+
+ copy-dependencies
+
+ initialize
+
+
+ copy-dependencies
+
+
+
+ true
+
+ ${project.basedir}/lib
+
+ ${project.basedir}/lib
+
+
+
+
+
+
+ org.apache.maven.plugins
+
+ maven-clean-plugin
+
+
+
+ clean-dependencies
+ clean
+
+
+ clean
+
+
+
+
+
+
+ lib
+
+
+
+ **/*
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/moclodash/fr.inria.diverse.cloning.materialgenerator.cli.product/.project b/moclodash/fr.inria.diverse.cloning.materialgenerator.cli.product/.project
new file mode 100644
index 0000000000000000000000000000000000000000..aae38ee7204d2829ae5e9b1b390dded9954d2019
--- /dev/null
+++ b/moclodash/fr.inria.diverse.cloning.materialgenerator.cli.product/.project
@@ -0,0 +1,11 @@
+
+
+ fr.inria.diverse.cloning.materialgenerator.cli.product
+
+
+
+
+
+
+
+
diff --git a/moclodash/fr.inria.diverse.cloning.materialgenerator.cli.product/main.product b/moclodash/fr.inria.diverse.cloning.materialgenerator.cli.product/main.product
new file mode 100644
index 0000000000000000000000000000000000000000..8be1e142cf3f816fb302926fd445f562379d4847
--- /dev/null
+++ b/moclodash/fr.inria.diverse.cloning.materialgenerator.cli.product/main.product
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
+ -XstartOnFirstThread -Dorg.eclipse.swt.internal.carbon.smallFonts
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/moclodash/fr.inria.diverse.cloning.materialgenerator.cli.product/pom.xml b/moclodash/fr.inria.diverse.cloning.materialgenerator.cli.product/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..957f58d15d4d4fce18e245ca112f5f786c8e0c3c
--- /dev/null
+++ b/moclodash/fr.inria.diverse.cloning.materialgenerator.cli.product/pom.xml
@@ -0,0 +1,48 @@
+
+
+
+ 4.0.0
+ fr.inria.diverse.cloning
+ fr.inria.diverse.cloning.materialgenerator.cli.product
+ 0.1.0-SNAPSHOT
+ eclipse-repository
+
+
+ fr.inria.diverse.cloning
+ moclodash
+ 0.1.0-SNAPSHOT
+
+
+
+
+
+
+
+ org.eclipse.tycho
+ tycho-p2-director-plugin
+ ${tycho.version}
+
+
+ create-product-distributions
+
+ materialize-products
+ archive-products
+
+
+
+
+
+
+
+
+
diff --git a/moclodash/fr.inria.diverse.cloning.materialgenerator.cli/.classpath b/moclodash/fr.inria.diverse.cloning.materialgenerator.cli/.classpath
new file mode 100644
index 0000000000000000000000000000000000000000..098194ca4b7d8f45177f94e735506ae3a26b5c94
--- /dev/null
+++ b/moclodash/fr.inria.diverse.cloning.materialgenerator.cli/.classpath
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/moclodash/fr.inria.diverse.cloning.materialgenerator.cli/.gitignore b/moclodash/fr.inria.diverse.cloning.materialgenerator.cli/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..5e56e040ec0902e58df8573adaec65c5da6e9304
--- /dev/null
+++ b/moclodash/fr.inria.diverse.cloning.materialgenerator.cli/.gitignore
@@ -0,0 +1 @@
+/bin
diff --git a/moclodash/fr.inria.diverse.cloning.materialgenerator.cli/.project b/moclodash/fr.inria.diverse.cloning.materialgenerator.cli/.project
new file mode 100644
index 0000000000000000000000000000000000000000..8a18f018784a0cd7d1cb25686bd04a4893c56f9a
--- /dev/null
+++ b/moclodash/fr.inria.diverse.cloning.materialgenerator.cli/.project
@@ -0,0 +1,28 @@
+
+
+ fr.inria.diverse.cloning.materialgenerator.cli
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ org.eclipse.pde.ManifestBuilder
+
+
+
+
+ org.eclipse.pde.SchemaBuilder
+
+
+
+
+
+ org.eclipse.pde.PluginNature
+ org.eclipse.jdt.core.javanature
+
+
diff --git a/moclodash/fr.inria.diverse.cloning.materialgenerator.cli/.settings/org.eclipse.jdt.core.prefs b/moclodash/fr.inria.diverse.cloning.materialgenerator.cli/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..f42de363afaae68bbd968318f1d331877f5514fc
--- /dev/null
+++ b/moclodash/fr.inria.diverse.cloning.materialgenerator.cli/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,7 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
+org.eclipse.jdt.core.compiler.compliance=1.7
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.7
diff --git a/moclodash/fr.inria.diverse.cloning.materialgenerator.cli/META-INF/MANIFEST.MF b/moclodash/fr.inria.diverse.cloning.materialgenerator.cli/META-INF/MANIFEST.MF
new file mode 100644
index 0000000000000000000000000000000000000000..10b64dd643ab7d48be304a2da5c1138c70741895
--- /dev/null
+++ b/moclodash/fr.inria.diverse.cloning.materialgenerator.cli/META-INF/MANIFEST.MF
@@ -0,0 +1,12 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: App
+Bundle-SymbolicName: fr.inria.diverse.cloning.materialgenerator.cli;singleton:=true
+Bundle-Version: 0.1.0.qualifier
+Require-Bundle: org.eclipse.core.runtime,
+ org.eclipse.core.resources,
+ org.eclipse.jdt.core,
+ fr.inria.diverse.cloning.materialgenerator,
+ fr.inria.diverse.cloning.external-libs;bundle-version="0.1.0"
+Bundle-RequiredExecutionEnvironment: JavaSE-1.7
+Bundle-ClassPath: .
diff --git a/moclodash/fr.inria.diverse.cloning.materialgenerator.cli/build.properties b/moclodash/fr.inria.diverse.cloning.materialgenerator.cli/build.properties
new file mode 100644
index 0000000000000000000000000000000000000000..d3ec1bc5a89e4ffd2fb31c5d8a13897fc4cbdd3f
--- /dev/null
+++ b/moclodash/fr.inria.diverse.cloning.materialgenerator.cli/build.properties
@@ -0,0 +1,5 @@
+output.. = bin/
+bin.includes = plugin.xml,\
+ META-INF/,\
+ .
+source.. = src/
diff --git a/moclodash/fr.inria.diverse.cloning.materialgenerator.cli/plugin.xml b/moclodash/fr.inria.diverse.cloning.materialgenerator.cli/plugin.xml
new file mode 100644
index 0000000000000000000000000000000000000000..e750e0b7fc67c1e39eff6de14a71ffdafc81cc0e
--- /dev/null
+++ b/moclodash/fr.inria.diverse.cloning.materialgenerator.cli/plugin.xml
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/moclodash/fr.inria.diverse.cloning.materialgenerator.cli/pom.xml b/moclodash/fr.inria.diverse.cloning.materialgenerator.cli/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..7e07cc823fbd6361048d6c4189a8b94fcd81ac8e
--- /dev/null
+++ b/moclodash/fr.inria.diverse.cloning.materialgenerator.cli/pom.xml
@@ -0,0 +1,27 @@
+
+
+
+ 4.0.0
+ fr.inria.diverse.cloning
+ fr.inria.diverse.cloning.materialgenerator.cli
+ 0.1.0-SNAPSHOT
+ eclipse-plugin
+
+
+ fr.inria.diverse.cloning
+ moclodash
+ 0.1.0-SNAPSHOT
+
+
+
+
diff --git a/moclodash/fr.inria.diverse.cloning.materialgenerator.cli/src/fr/inria/diverse/cloning/materialgenerator/cli/Application.java b/moclodash/fr.inria.diverse.cloning.materialgenerator.cli/src/fr/inria/diverse/cloning/materialgenerator/cli/Application.java
new file mode 100644
index 0000000000000000000000000000000000000000..e414bfd37642593bd7a86b0c43f0e8a5fa364e44
--- /dev/null
+++ b/moclodash/fr.inria.diverse.cloning.materialgenerator.cli/src/fr/inria/diverse/cloning/materialgenerator/cli/Application.java
@@ -0,0 +1,105 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Université de Rennes 1.
+ * 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:
+ * Erwan Bousse - initial API and implementation
+ ******************************************************************************/
+package fr.inria.diverse.cloning.materialgenerator.cli;
+
+import java.io.File;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import joptsimple.OptionException;
+import joptsimple.OptionParser;
+import joptsimple.OptionSet;
+import joptsimple.OptionSpec;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IProjectDescription;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.equinox.app.IApplication;
+import org.eclipse.equinox.app.IApplicationContext;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.JavaCore;
+
+import fr.inria.diverse.cloning.materialgenerator.start.Start;
+
+/**
+ * This class controls all aspects of the application's execution
+ */
+public class Application implements IApplication {
+
+ /*
+ *
+ *
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.equinox.app.IApplication#start(org.eclipse.equinox.app. IApplicationContext)
+ */
+ public Object start(IApplicationContext context) throws Exception {
+
+ String[] args = (String[]) context.getArguments().get(IApplicationContext.APPLICATION_ARGS);
+
+ // Specifying arguments
+ OptionParser parser = new OptionParser();
+
+ OptionSpec ecoreFilesOption = parser.accepts("ecoreFiles", "The ecore files describing the metamodel.")
+ .withRequiredArg().required().describedAs("path1,path2,...").ofType(File.class)
+ .withValuesSeparatedBy(",").required();
+
+ OptionSpec emfProjectFolderOption = parser
+ .accepts("emfProjectFolder", "The folder of the eclipse java project with generated emf code.")
+ .withRequiredArg().required().describedAs("path").ofType(File.class).required();
+
+ OptionSpec metamodelNameOption = parser.accepts("metamodelName", "The name of the metamodel.")
+ .withRequiredArg().required().ofType(String.class).required();
+
+ OptionSpec> emfGenerationOption = parser.accepts("generateEMFcode",
+ "Whether the EMF model code should be generated, with appropriate super types for classes.");
+
+ try {
+
+ // Parsing arguments (throws an error if problem)
+ OptionSet options = parser.parse(args);
+ List ecoreFiles = options.valuesOf(ecoreFilesOption);
+ Set ecoreFilesSet = new HashSet(ecoreFiles);
+ File emfProjectFolder = options.valueOf(emfProjectFolderOption);
+ String metamodelName = options.valueOf(metamodelNameOption);
+ boolean emfGen = options.has(emfGenerationOption);
+
+ // Creating a "fake" java project from a real existing eclipse java // project on the filesystem
+ IProjectDescription description = ResourcesPlugin.getWorkspace().loadProjectDescription(
+ new Path(new File(emfProjectFolder, ".project").getAbsolutePath()));
+ IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(description.getName());
+ project.delete(false, true, null);
+ project.create(description, null);
+ project.open(null);
+ IJavaProject javaProject = JavaCore.create(project);
+
+ Start.start(ecoreFilesSet, metamodelName, javaProject, emfGen);
+
+ } catch (OptionException e) {
+ System.out.println("Invalid options: " + e.getMessage());
+ parser.printHelpOn(System.out);
+ }
+
+ return IApplication.EXIT_OK;
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.equinox.app.IApplication#stop()
+ */
+ public void stop() {
+ // nothing to do
+ }
+}
diff --git a/moclodash/fr.inria.diverse.cloning.materialgenerator/.classpath b/moclodash/fr.inria.diverse.cloning.materialgenerator/.classpath
new file mode 100644
index 0000000000000000000000000000000000000000..db3449225d861a2829a4297e48cb62048f162ef0
--- /dev/null
+++ b/moclodash/fr.inria.diverse.cloning.materialgenerator/.classpath
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/moclodash/fr.inria.diverse.cloning.materialgenerator/.gitignore b/moclodash/fr.inria.diverse.cloning.materialgenerator/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..5e56e040ec0902e58df8573adaec65c5da6e9304
--- /dev/null
+++ b/moclodash/fr.inria.diverse.cloning.materialgenerator/.gitignore
@@ -0,0 +1 @@
+/bin
diff --git a/moclodash/fr.inria.diverse.cloning.materialgenerator/.project b/moclodash/fr.inria.diverse.cloning.materialgenerator/.project
new file mode 100644
index 0000000000000000000000000000000000000000..b0578112b735fbc5b1c059bef78e69bdb4560739
--- /dev/null
+++ b/moclodash/fr.inria.diverse.cloning.materialgenerator/.project
@@ -0,0 +1,28 @@
+
+
+ fr.inria.diverse.cloning.materialgenerator
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ org.eclipse.pde.ManifestBuilder
+
+
+
+
+ org.eclipse.pde.SchemaBuilder
+
+
+
+
+
+ org.eclipse.pde.PluginNature
+ org.eclipse.jdt.core.javanature
+
+
diff --git a/moclodash/fr.inria.diverse.cloning.materialgenerator/.settings/org.eclipse.core.resources.prefs b/moclodash/fr.inria.diverse.cloning.materialgenerator/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..a0425b2cce0901ac32e5faeb88977be5a6234b6b
--- /dev/null
+++ b/moclodash/fr.inria.diverse.cloning.materialgenerator/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+encoding//testdata/mm8.ecorediag=UTF-8
diff --git a/moclodash/fr.inria.diverse.cloning.materialgenerator/.settings/org.eclipse.jdt.core.prefs b/moclodash/fr.inria.diverse.cloning.materialgenerator/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..7341ab1683c4f1bd2f33bbd3d102ebf032569b57
--- /dev/null
+++ b/moclodash/fr.inria.diverse.cloning.materialgenerator/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,11 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.7
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.7
diff --git a/moclodash/fr.inria.diverse.cloning.materialgenerator/META-INF/MANIFEST.MF b/moclodash/fr.inria.diverse.cloning.materialgenerator/META-INF/MANIFEST.MF
new file mode 100644
index 0000000000000000000000000000000000000000..cd758ad88eba239b27559fa853853269b1c0cdc6
--- /dev/null
+++ b/moclodash/fr.inria.diverse.cloning.materialgenerator/META-INF/MANIFEST.MF
@@ -0,0 +1,37 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: CloningMaterialGenerator
+Bundle-SymbolicName: fr.inria.diverse.cloning.materialgenerator;singleton:=true
+Bundle-Version: 0.1.0.qualifier
+Require-Bundle: org.eclipse.core.runtime,
+ org.eclipse.gmt.modisco.java.generation;bundle-version="0.11.1",
+ org.eclipse.emf.common,
+ org.eclipse.emf.ecore;bundle-version="2.9.1",
+ org.eclipse.modisco.java.discoverer;bundle-version="0.11.1",
+ org.eclipse.modisco.infra.discovery.core;bundle-version="0.11.1",
+ org.eclipse.core.resources;bundle-version="3.8.101",
+ org.eclipse.jdt.core;bundle-version="3.9.1",
+ org.eclipse.equinox.registry,
+ org.eclipse.gmt.modisco.java;bundle-version="0.11.1",
+ org.eclipse.emf.ecore.xmi;bundle-version="2.9.1",
+ org.eclipse.gmf.runtime.emf.core;bundle-version="1.7.0",
+ fr.inria.diverse.cloning.runtime;bundle-version="0.1.0",
+ org.eclipse.emf.codegen;bundle-version="2.9.0",
+ org.eclipse.emf.codegen.ecore;bundle-version="2.9.1",
+ org.eclipse.jface.text;bundle-version="3.8.101",
+ org.eclipse.ui;bundle-version="3.105.0",
+ org.eclipse.core.variables;bundle-version="3.2.700",
+ org.eclipse.debug.core;bundle-version="3.8.0",
+ org.eclipse.jdt.launching;bundle-version="3.7.0",
+ org.eclipse.debug.ui;bundle-version="3.9.0",
+ org.eclipse.jdt.debug.ui;bundle-version="3.6.200",
+ org.eclipse.ui.ide;bundle-version="3.9.1",
+ org.eclipse.ui.console
+Bundle-RequiredExecutionEnvironment: JavaSE-1.7
+Export-Package: fr.inria.diverse.cloning.materialgenerator.generators,
+ fr.inria.diverse.cloning.materialgenerator.metrics,
+ fr.inria.diverse.cloning.materialgenerator.start,
+ fr.inria.diverse.cloning.materialgenerator.tagger,
+ fr.inria.diverse.cloning.materialgenerator.tagger.impl,
+ fr.inria.diverse.cloning.materialgenerator.util
+Bundle-ClassPath: .
diff --git a/moclodash/fr.inria.diverse.cloning.materialgenerator/build.properties b/moclodash/fr.inria.diverse.cloning.materialgenerator/build.properties
new file mode 100644
index 0000000000000000000000000000000000000000..2b0d95b6b02b49d14dbb5f6940aa13b6f13bce29
--- /dev/null
+++ b/moclodash/fr.inria.diverse.cloning.materialgenerator/build.properties
@@ -0,0 +1,5 @@
+source.. = src/
+output.. = bin/
+bin.includes = plugin.xml,\
+ META-INF/,\
+ .
diff --git a/moclodash/fr.inria.diverse.cloning.materialgenerator/javamodel/javamodel.xmi b/moclodash/fr.inria.diverse.cloning.materialgenerator/javamodel/javamodel.xmi
new file mode 100644
index 0000000000000000000000000000000000000000..12e29c381b857b64bb790af797c3691352b0cc2d
--- /dev/null
+++ b/moclodash/fr.inria.diverse.cloning.materialgenerator/javamodel/javamodel.xmi
@@ -0,0 +1,238 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/moclodash/fr.inria.diverse.cloning.materialgenerator/plugin.xml b/moclodash/fr.inria.diverse.cloning.materialgenerator/plugin.xml
new file mode 100644
index 0000000000000000000000000000000000000000..1ba757994fbfa1f064ccccddad75efa712b532e3
--- /dev/null
+++ b/moclodash/fr.inria.diverse.cloning.materialgenerator/plugin.xml
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/moclodash/fr.inria.diverse.cloning.materialgenerator/pom.xml b/moclodash/fr.inria.diverse.cloning.materialgenerator/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..161720787b74798e4330c80023ef6b5b8d132d7a
--- /dev/null
+++ b/moclodash/fr.inria.diverse.cloning.materialgenerator/pom.xml
@@ -0,0 +1,28 @@
+
+
+
+ 4.0.0
+ fr.inria.diverse.cloning
+ fr.inria.diverse.cloning.materialgenerator
+ 0.1.0-SNAPSHOT
+ eclipse-plugin
+
+
+
+ fr.inria.diverse.cloning
+ moclodash
+ 0.1.0-SNAPSHOT
+
+
+
+
diff --git a/moclodash/fr.inria.diverse.cloning.materialgenerator/src/fr/inria/diverse/cloning/materialgenerator/generators/CloningMaterialClassGenerator.java b/moclodash/fr.inria.diverse.cloning.materialgenerator/src/fr/inria/diverse/cloning/materialgenerator/generators/CloningMaterialClassGenerator.java
new file mode 100644
index 0000000000000000000000000000000000000000..de9971bc8663fd3c64445358c34b5955c23b1fac
--- /dev/null
+++ b/moclodash/fr.inria.diverse.cloning.materialgenerator/src/fr/inria/diverse/cloning/materialgenerator/generators/CloningMaterialClassGenerator.java
@@ -0,0 +1,110 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Université de Rennes 1.
+ * 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:
+ * Erwan Bousse - initial API and implementation
+ ******************************************************************************/
+package fr.inria.diverse.cloning.materialgenerator.generators;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.PrintStream;
+
+import org.eclipse.emf.ecore.resource.ResourceSet;
+import fr.inria.diverse.cloning.runtime.emfextension.impl.LooseCopier;
+
+import fr.inria.diverse.cloning.materialgenerator.tagger.Tagger;
+import fr.inria.diverse.cloning.materialgenerator.util.CodeGeneration;
+import fr.inria.diverse.cloning.runtime.common.CloningMaterial;
+import fr.inria.diverse.cloning.runtime.common.MetamodelTags;
+
+public class CloningMaterialClassGenerator {
+ /**
+ * Generates a java class implementing the MetamodelTags interface, to retrieve at runtine the generate tags of the
+ * metamodel classes.
+ *
+ * @param pack
+ * The java package in which to generate the class.
+ * @param srcOutputFolder
+ * The source folder in which all the model code is located.
+ */
+ public static void generateCloningMaterialClass(ResourceSet metamodel, String javapackagename, File outputDir, Tagger tagger) {
+ // Computing the class name
+ String className = CodeGeneration.firstCharUp(tagger.getMetamodelName() + tagger.getCloningName()
+ + Constants.CLONING_MATERIAL__SUFFIX);
+ String tagsClassName = CodeGeneration.firstCharUp(tagger.getMetamodelName() + tagger.getCloningName()
+ + Constants.TAGS_SUFFIX);
+
+ try {
+ // Preparing the output file
+ //File outputDir = new File(srcOutputFolder + "/" + generateFullyQualifiedName(pack, "/"));
+ outputDir.mkdirs();
+ File outputFile = new File(outputDir, className + ".java");
+ outputFile.createNewFile();
+ PrintStream printer = new PrintStream(outputFile);
+
+ // Package header
+ printer.println("package " + javapackagename + ";\n");
+
+ String imports = "";
+
+ // Imports not metamodel dependent
+ imports += "import " + CloningMaterial.class.getCanonicalName() + ";\n";
+ //imports += "import " + LooseCopier.class.getCanonicalName() + ";\n";
+ imports += "import " + MetamodelTags.class.getCanonicalName() + ";\n";
+ imports += "import " + LooseCopier.class.getCanonicalName() + ";\n";
+
+ // Class declaration
+ String classdef = "public class " + className + " implements " + CloningMaterial.class.getSimpleName()
+ + " {\n";
+
+ // private instance declaration
+ classdef += "private static " + className + " instance;\n";
+ classdef += "private " + tagsClassName + " tags;\n";
+
+ // private constructor declaration
+ classdef += "private " + className + "(" + tagsClassName + " tags){" + "this.tags = tags;\n" + "};\n";
+
+ // getInstance method declaration
+ classdef += "public static " + className + " getInstance() {\n";
+ classdef += "if (instance == null)\n";
+ classdef += "instance = new " + className + "(new " + tagsClassName + "());\n";
+ classdef += "return instance;\n";
+ // end init method declaration
+ classdef += "}\n";
+
+ // getTags method declaration
+ classdef += "public " + MetamodelTags.class.getSimpleName() + " getTags() {\n";
+ classdef += "return tags;";
+ // end getTags method declarationCopier
+ classdef += "}\n";
+
+ // createLightCopier method declaration
+ String copierClassName = CodeGeneration.firstCharUp(tagger.getMetamodelName() + tagger.getCloningName()
+ + Constants.COPIER_SUFFIX);
+ classdef += "public " + LooseCopier.class.getSimpleName() + " createCopier() {\n";
+ if (tagger.mayTagClassesPartShareable())
+ classdef += "return new " + copierClassName + "();";
+ else
+ classdef += "return new LooseCopier ();";
+ // end createLightCopier method declaration
+ classdef += "}\n";
+
+ // end class declaration
+ classdef += "}\n";
+
+ // Then ultimately we put all this studd in a file
+ printer.println(imports);
+ printer.println(classdef);
+ printer.close();
+ } catch (IOException e) {
+ System.err.println("Impossible to write cloning material class " + className + "!");
+ e.printStackTrace();
+ }
+
+ }
+}
diff --git a/moclodash/fr.inria.diverse.cloning.materialgenerator/src/fr/inria/diverse/cloning/materialgenerator/generators/Constants.java b/moclodash/fr.inria.diverse.cloning.materialgenerator/src/fr/inria/diverse/cloning/materialgenerator/generators/Constants.java
new file mode 100644
index 0000000000000000000000000000000000000000..86e2c37ba5b835c4c0788435d447b3124010e717
--- /dev/null
+++ b/moclodash/fr.inria.diverse.cloning.materialgenerator/src/fr/inria/diverse/cloning/materialgenerator/generators/Constants.java
@@ -0,0 +1,20 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Université de Rennes 1.
+ * 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:
+ * Erwan Bousse - initial API and implementation
+ ******************************************************************************/
+package fr.inria.diverse.cloning.materialgenerator.generators;
+
+public class Constants {
+
+ public static final String COPIER_SUFFIX = "Copier";
+ public static final String TAGS_SUFFIX = "Tags";
+ public static final String CLONING_MATERIAL__SUFFIX = "CloningMaterial";
+ public static final String METRICS__SUFFIX = "Metrics";
+
+}
diff --git a/moclodash/fr.inria.diverse.cloning.materialgenerator/src/fr/inria/diverse/cloning/materialgenerator/generators/EMFCodeGenerator.java b/moclodash/fr.inria.diverse.cloning.materialgenerator/src/fr/inria/diverse/cloning/materialgenerator/generators/EMFCodeGenerator.java
new file mode 100644
index 0000000000000000000000000000000000000000..75fae5df8bdab65fe4ffc9aced139accbff99168
--- /dev/null
+++ b/moclodash/fr.inria.diverse.cloning.materialgenerator/src/fr/inria/diverse/cloning/materialgenerator/generators/EMFCodeGenerator.java
@@ -0,0 +1,136 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Université de Rennes 1.
+ * 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:
+ * Erwan Bousse - initial API and implementation
+ ******************************************************************************/
+package fr.inria.diverse.cloning.materialgenerator.generators;
+
+import java.io.File;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.emf.codegen.ecore.generator.Generator;
+import org.eclipse.emf.codegen.ecore.genmodel.GenJDKLevel;
+import org.eclipse.emf.codegen.ecore.genmodel.GenModel;
+import org.eclipse.emf.codegen.ecore.genmodel.GenModelFactory;
+import org.eclipse.emf.codegen.ecore.genmodel.generator.GenBaseGeneratorAdapter;
+import org.eclipse.emf.common.util.BasicDiagnostic;
+import org.eclipse.emf.common.util.BasicMonitor;
+import org.eclipse.emf.common.util.Diagnostic;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.EPackage;
+import org.eclipse.emf.ecore.EcorePackage;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.resource.ResourceSet;
+import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
+import org.eclipse.emf.ecore.util.Diagnostician;
+import org.eclipse.emf.ecore.xmi.impl.EcoreResourceFactoryImpl;
+
+import fr.inria.diverse.cloning.runtime.util.EcoreHelper;
+
+public class EMFCodeGenerator {
+
+ private static final String rootClassName = fr.inria.diverse.cloning.runtime.emfextension.impl.AbstractShareableEObject.class
+ .getCanonicalName();
+
+ private static final boolean overrideInterface = false;
+ private static final String rootInterfaceName = fr.inria.diverse.cloning.runtime.emfextension.ShareableEObject.class
+ .getCanonicalName();
+
+ /**
+ * Exception thrown when the ecore file is not valid.
+ *
+ * @author ebousse
+ *
+ */
+ public static class EMFGenerationException extends Exception {
+ private static final long serialVersionUID = -7761342805184071165L;
+ String message;
+
+ public EMFGenerationException(String message) {
+ this.message = message;
+ }
+
+ @Override
+ public String getMessage() {
+ return message;
+ }
+ }
+
+ /**
+ * Generator operation.
+ *
+ * @param serializedMetamodel
+ * Ecore files that represent a metamodel.
+ * @param metamodelname
+ * The name to consider for the metamodel.
+ * @param project
+ * The Eclipse project in which the code should be generated.
+ * @return The loaded metamodel in memory, for further use.
+ * @throws EMFGenerationException
+ * If an ecore file is invalid.
+ */
+ public static ResourceSet generate(Set serializedMetamodel, String metamodelname, IProject project)
+ throws EMFGenerationException {
+
+ // First loading all the ecore files
+ EcoreResourceFactoryImpl fact = new EcoreResourceFactoryImpl();
+ if (!EPackage.Registry.INSTANCE.containsKey(EcorePackage.eNS_URI))
+ EPackage.Registry.INSTANCE.put(EcorePackage.eNS_URI, EcorePackage.eINSTANCE);
+ Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap().put("ecore", fact);
+ ResourceSet rs = new ResourceSetImpl();
+ for (File f : serializedMetamodel)
+ rs.getResource(URI.createFileURI(f.getAbsolutePath()), true);
+
+ // Then finding all the EPackages (we consider a single root package per ecore file)
+ Set rootPackages = new HashSet();
+ for (Resource resource : rs.getResources())
+ rootPackages.add((EPackage) resource.getContents().get(0));
+
+ // Analysing all EPackages
+ BasicDiagnostic diagnosticChain = new BasicDiagnostic();
+ for (EPackage ePackage : EcoreHelper.findEPackages(rs))
+ Diagnostician.INSTANCE.validate(ePackage, diagnosticChain);
+ if (diagnosticChain.getSeverity() != Diagnostic.ERROR) {
+
+ GenModel genModel = GenModelFactory.eINSTANCE.createGenModel();
+ genModel.setComplianceLevel(GenJDKLevel.JDK70_LITERAL);
+ genModel.setModelDirectory("/" + project.getName() + "/src");
+ for (File f : serializedMetamodel)
+ genModel.getForeignModel().add(new Path(f.getAbsolutePath()).lastSegment());
+ genModel.setModelName(metamodelname);
+ genModel.setRootExtendsClass(rootClassName);
+ if (overrideInterface)
+ genModel.setRootExtendsInterface(rootInterfaceName);
+ genModel.initialize(rootPackages);
+ genModel.reconcile();
+ genModel.setCanGenerate(true);
+ genModel.setValidateModel(true);
+
+ // Generating the model code from the genmodel
+ Generator generator = new Generator();
+ generator.setInput(genModel);
+ generator.generate(genModel, GenBaseGeneratorAdapter.MODEL_PROJECT_TYPE, "model project", new BasicMonitor());
+ //generator.generate(genModel, GenBaseGeneratorAdapter.MODEL_PROJECT_TYPE, "model project",null);
+
+ } else {
+
+ String message = "Couldnt generate EMF code because of an invalid ecore file. Message: ";
+ for (Diagnostic d : diagnosticChain.getChildren()) {
+ if (d.getSeverity() == Diagnostic.ERROR)
+ message += d.getMessage();
+ }
+ throw new EMFGenerationException(message);
+
+ }
+
+ return rs;
+ }
+}
diff --git a/moclodash/fr.inria.diverse.cloning.materialgenerator/src/fr/inria/diverse/cloning/materialgenerator/generators/EMFImpl2PImpl.java b/moclodash/fr.inria.diverse.cloning.materialgenerator/src/fr/inria/diverse/cloning/materialgenerator/generators/EMFImpl2PImpl.java
new file mode 100644
index 0000000000000000000000000000000000000000..91b090f9e8170d87cb629a49c83da1f7ae95ca8f
--- /dev/null
+++ b/moclodash/fr.inria.diverse.cloning.materialgenerator/src/fr/inria/diverse/cloning/materialgenerator/generators/EMFImpl2PImpl.java
@@ -0,0 +1,720 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Université de Rennes 1.
+ * 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:
+ * Erwan Bousse - initial API and implementation
+ ******************************************************************************/
+package fr.inria.diverse.cloning.materialgenerator.generators;
+
+import java.io.File;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.emf.common.util.BasicEList;
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EClassifier;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EPackage;
+import org.eclipse.emf.ecore.EPackage.Registry;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.util.EcoreUtil;
+import org.eclipse.emf.ecore.util.EcoreUtil.Copier;
+import org.eclipse.gmt.modisco.java.AbstractTypeDeclaration;
+import org.eclipse.gmt.modisco.java.Assignment;
+import org.eclipse.gmt.modisco.java.BodyDeclaration;
+import org.eclipse.gmt.modisco.java.ClassDeclaration;
+import org.eclipse.gmt.modisco.java.CompilationUnit;
+import org.eclipse.gmt.modisco.java.ConstructorDeclaration;
+import org.eclipse.gmt.modisco.java.ExpressionStatement;
+import org.eclipse.gmt.modisco.java.FieldDeclaration;
+import org.eclipse.gmt.modisco.java.InterfaceDeclaration;
+import org.eclipse.gmt.modisco.java.MethodDeclaration;
+import org.eclipse.gmt.modisco.java.MethodInvocation;
+import org.eclipse.gmt.modisco.java.Model;
+import org.eclipse.gmt.modisco.java.Modifier;
+import org.eclipse.gmt.modisco.java.Package;
+import org.eclipse.gmt.modisco.java.ReturnStatement;
+import org.eclipse.gmt.modisco.java.SingleVariableAccess;
+import org.eclipse.gmt.modisco.java.SingleVariableDeclaration;
+import org.eclipse.gmt.modisco.java.Statement;
+import org.eclipse.gmt.modisco.java.StringLiteral;
+import org.eclipse.gmt.modisco.java.TypeAccess;
+import org.eclipse.gmt.modisco.java.VariableDeclaration;
+import org.eclipse.gmt.modisco.java.VariableDeclarationFragment;
+import org.eclipse.gmt.modisco.java.VisibilityKind;
+import org.eclipse.gmt.modisco.java.emf.JavaFactory;
+
+import fr.inria.diverse.cloning.materialgenerator.tagger.Tagger;
+import fr.inria.diverse.cloning.runtime.common.ClassTag;
+import fr.inria.diverse.cloning.runtime.util.Log;
+
+public class EMFImpl2PImpl {
+
+ /**
+ * MetaClasses mapping between the Java model and the Ecore model.
+ */
+ private Map classesMapping;
+
+ /**
+ * Properties mapping between the Java model and the Ecore model.
+ */
+ private Map propertiesMapping;
+
+ /**
+ * Java classes that will be used as bases in the generation process.
+ */
+ private Set toProcess;
+
+ /**
+ * All the java classes implementing metaclasses
+ */
+ private Set wholeMetamodel;
+
+ /**
+ * The model to transform
+ */
+ private Model javaModel;
+
+ /**
+ * The cloning tagger to consider. It completely drives the transformation regarding what is mutable or not.
+ */
+ private Tagger tagger;
+
+ private boolean readonlyWarningsInSetters;
+
+ /**
+ * Retrieves from the tagger the mutability tag of a java class that implements a metaclass.
+ *
+ * @param classd
+ * A java class that implements a metaclass.
+ * @return The tag of the metaclass (telling how mutable it is)
+ */
+ private ClassTag getTagOfClass(ClassDeclaration classd) {
+ return getTagOfInterface((InterfaceDeclaration) classd.getSuperInterfaces().get(0).getType());
+ }
+
+ /**
+ * Retrieves from the tagger the mutability tag of a java interfaces that corresponds to a metaclass.
+ *
+ * @param classd
+ * A java interfaces that matches a metaclass.
+ * @return The tag of the metaclass (telling how mutable it is)
+ */
+ private ClassTag getTagOfInterface(InterfaceDeclaration classd) {
+ return tagger.getTagOfEClass(classesMapping.get(classd));
+ }
+
+ /**
+ * Retrieves from the tagger the mutability (mutable or not) of a java property that implements a metaclass
+ * property.
+ *
+ * @param vard
+ * The java property that implements a metaclass property.
+ * @return True if the metaproperty is mutable, false otherwise.
+ */
+ private boolean isFieldShareable(VariableDeclarationFragment vard) {
+ return tagger.isPropertyShareable(propertiesMapping.get(vard));
+ }
+
+ /**
+ * To decide whether a property is mutable or not. Only relies on its name, which should end with "_m" or
+ * "_M_EDEFAULT" for default values.
+ *
+ * @param variable
+ * The variable to analyse
+ * @return True if mutable, false otherwise.
+ */
+ /*
+ * private boolean isMutable(VariableDeclarationFragment variable) {
+ *
+ * boolean pointsToMutable = false; if (variable.getVariablesContainer() instanceof FieldDeclaration) {
+ * FieldDeclaration fieldd = (FieldDeclaration) variable.getVariablesContainer(); if (fieldd.getType() != null &&
+ * fieldd.getType().getType() instanceof InterfaceDeclaration) { InterfaceDeclaration interfaced =
+ * (InterfaceDeclaration) fieldd.getType().getType(); ClassTag tag = getTagOfInterface(interfaced);
+ *
+ * switch (tag) { // case canReachMutable: // pointsToMutable = true; case completelyMutable: pointsToMutable =
+ * true; case completelyReadonly: pointsToMutable = false; case partiallyMutable: pointsToMutable = true; }
+ *
+ * }
+ *
+ * }
+ *
+ * return pointsToMutable || variable.getName().endsWith("_m") || variable.getName().endsWith("_M_EDEFAULT"); }
+ */
+
+ /**
+ * Helper method that allows one to find the method that contain some model element.
+ *
+ * @param o
+ * The model element.
+ * @return The method containing the model element.
+ */
+ private static MethodDeclaration getContainingMethod(EObject o) {
+ if (o.eContainer() != null) {
+ if (o.eContainer() instanceof MethodDeclaration)
+ return (MethodDeclaration) o.eContainer();
+ else
+ return getContainingMethod(o.eContainer());
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Constructor of the transformation. Parameterized by the model to transform and the tagger used.
+ *
+ * @param javaModel
+ * @param tagger
+ */
+ public EMFImpl2PImpl(Model javaModel, Tagger tagger, boolean readonlyWarningsInSetters) {
+ super();
+ this.javaModel = javaModel;
+ this.tagger = tagger;
+ this.classesMapping = new HashMap();
+ this.propertiesMapping = new HashMap();
+ this.toProcess = new HashSet();
+ this.wholeMetamodel = new HashSet();
+ this.readonlyWarningsInSetters = readonlyWarningsInSetters;
+ computeMapping();
+ }
+
+ /**
+ * Helper method to create "System..println()" calls in the code. Creates a fake System class, a
+ * fake err static property, and a fake printlnt method. Then creates the call itself and return it.
+ *
+ * @param message
+ * The message that should be printed by the call.
+ * @param stream
+ * Either "out" or "err".
+ * @return The method call.
+ */
+ private ExpressionStatement createPrint(String message, String stream) {
+
+ // Preparing the factory
+ JavaFactory javaFactory = (JavaFactory) Registry.INSTANCE
+ .getEFactory("http://www.eclipse.org/MoDisco/Java/0.2.incubation/java");
+
+ // Fake "err" static field of System
+ FieldDeclaration errField = javaFactory.createFieldDeclaration();
+ Modifier errModifier = javaFactory.createModifier();
+ errModifier.setStatic(true);
+ errField.setModifier(errModifier);
+ VariableDeclarationFragment err = javaFactory.createVariableDeclarationFragment();
+ err.setName(stream);
+ errField.getFragments().add(err);
+
+ // Fake println method
+ MethodDeclaration println = javaFactory.createMethodDeclaration();
+ println.setName("println");
+
+ // Argument for the call, which is the message
+ StringLiteral arg = javaFactory.createStringLiteral();
+ arg.setEscapedValue("\"" + message + "\"");
+
+ // Fake System class
+ ClassDeclaration system = javaFactory.createClassDeclaration();
+ system.setName("System");
+ system.getBodyDeclarations().add(println);
+ system.getBodyDeclarations().add(errField);
+
+ // To access to the system class
+ TypeAccess systemAccess = javaFactory.createTypeAccess();
+ systemAccess.setType(system);
+
+ // To access to the "err" field
+ SingleVariableAccess erraccess = javaFactory.createSingleVariableAccess();
+ erraccess.setVariable(err);
+ erraccess.setQualifier(systemAccess);
+
+ // Invocation of the fake println method
+ MethodInvocation printlncall = javaFactory.createMethodInvocation();
+ printlncall.setMethod(println);
+ printlncall.setExpression(erraccess);
+ printlncall.getArguments().add(arg);
+
+ // Finally creating the expression result, containing the invocation of println
+ ExpressionStatement result = javaFactory.createExpressionStatement();
+ result.setExpression(printlncall);
+
+ // And returning it
+ return result;
+ }
+
+ /**
+ * Helper method to find the getter of some property in the original model. For instance: in APImpl the attribute a
+ * would return the getA() method of AImpl.
+ *
+ * @param variable
+ * The property for which we need the original getter.
+ * @param copier
+ * The copier that produced the java model clone.
+ * @return
+ */
+ private MethodDeclaration findGetterInImpl(VariableDeclarationFragment variable, EcoreUtil.Copier copier) {
+
+ VariableDeclarationFragment realvariable = (VariableDeclarationFragment) copier.get(variable);
+
+ for (SingleVariableAccess access : realvariable.getUsageInVariableAccess()) {
+ if (access.eContainer() instanceof ReturnStatement) {
+ ReturnStatement ret = (ReturnStatement) access.eContainer();
+ if (ret.eContainer().eContainer() instanceof MethodDeclaration) {
+ MethodDeclaration potentialGetter = (MethodDeclaration) ret.eContainer().eContainer();
+ // If found return, the getter
+ if (potentialGetter.getName().startsWith("get") || potentialGetter.getName().startsWith("is"))
+ return potentialGetter;
+ }
+
+ }
+ }
+ // If not found, return null
+ return null;
+ }
+
+ /**
+ * Method called on each readonly field, from the processClass body.
+ *
+ * @param variabled
+ * The readonly field to transform.
+ * @param copier
+ * The copier used to obtain the clone for the transformation.
+ * @param classd
+ * The java class that contains the field.
+ * @param clonedVar
+ * The field in the java regular implementation
+ */
+ private void processShareableProperty(VariableDeclarationFragment variabled, Copier copier, ClassDeclaration classd,
+ VariableDeclaration clonedVar) {
+
+ // Preparing the factory
+ JavaFactory javaFactory = (JavaFactory) Registry.INSTANCE
+ .getEFactory("http://www.eclipse.org/MoDisco/Java/0.2.incubation/java");
+
+ // We iterate through its usages
+ for (SingleVariableAccess access : variabled.getUsageInVariableAccess()) {
+
+ // Getting the method that contains this write
+ MethodDeclaration containingMethod = getContainingMethod(access);
+
+ if (containingMethod != null) {
+
+ // case WRITE (setters)
+ if (containingMethod.getName().startsWith("basicSet") || containingMethod.getName().startsWith("set")) {
+
+ // If we are, we clear its content
+ containingMethod.getBody().getStatements().clear();
+ // and we replace it with some error printing
+ if (readonlyWarningsInSetters) {
+ ExpressionStatement printExpr = createPrint(
+ "[Info] " + classd.getName() + ": " + variabled.getName()
+ + " is readonly and cannot be set.", "out");
+ printExpr.setOriginalCompilationUnit(classd.getOriginalCompilationUnit());
+ containingMethod.getBody().getStatements().add(printExpr);
+ }
+ // If in a basicSet, we have to return the NotificationChain
+ if (containingMethod.getName().startsWith("basicSet")) {
+
+ SingleVariableAccess parameterAccess = javaFactory.createSingleVariableAccess();
+ parameterAccess.setVariable(containingMethod.getParameters().get(1));
+
+ ReturnStatement ret = javaFactory.createReturnStatement();
+ ret.setExpression(parameterAccess);
+
+ containingMethod.getBody().getStatements().add(ret);
+
+ }
+
+ }
+
+ // case READ
+ else {
+
+ if (containingMethod != null) {
+
+ // If we are in a getter, we remove everything except the return
+ // (i.e. we remove everything proxy related)
+ // TODO check if in a return ?
+ if (containingMethod.getName().startsWith("basicGet")
+ || containingMethod.getName().startsWith("get")
+ || containingMethod.getName().startsWith("is")) {
+ EList statements = new BasicEList();
+ statements.addAll(containingMethod.getBody().getStatements());
+ for (Statement s : statements)
+ if (!(s instanceof ReturnStatement))
+ containingMethod.getBody().getStatements().remove(s);
+ }
+
+ MethodDeclaration getter = findGetterInImpl(variabled, copier);
+
+ if (getter != null) {
+
+ // Creating the access to the cloned variable
+ SingleVariableAccess clonedAccess = javaFactory.createSingleVariableAccess();
+ clonedAccess.setVariable(clonedVar);
+
+ // Creating the call to the getter
+ MethodInvocation getCall = javaFactory.createMethodInvocation();
+ getCall.setMethod(getter);
+ getCall.setExpression(clonedAccess);
+
+ // Two cases : contained in a collection or not
+ // In both, we replace the access by cloned.get
+ if (access.eContainmentFeature().isMany()) {
+ @SuppressWarnings("unchecked")
+ EList list = (EList) access.eContainer().eGet(
+ access.eContainmentFeature());
+ list.set(list.indexOf(access), getCall);
+ } else {
+ access.eContainer().eSet(access.eContainmentFeature(), getCall);
+ }
+
+ }
+
+ }
+
+ }
+
+ }
+
+ }
+ }
+
+ /**
+ * Main transformation method.
+ *
+ * @param classd
+ * The class to process
+ * @param originalEclass
+ * @param copier
+ * The copier used to duplicate the java model
+ */
+ private void processClass(ClassDeclaration classd, Copier copier) {
+
+ String newName = classd.getName().substring(0, classd.getName().length() - 4) + tagger.getSuffix();
+
+ // Renaming the class
+ // String originalName = classd.getName();
+ classd.setName(newName);
+ classd.getOriginalCompilationUnit().setName(classd.getName() + ".java");
+
+ // Preparing the factory
+ JavaFactory javaFactory = (JavaFactory) Registry.INSTANCE
+ .getEFactory("http://www.eclipse.org/MoDisco/Java/0.2.incubation/java");
+
+ // Creating the "cloned" field...
+ // Added later to the class
+ // Maybe we should find the type in the original model ?
+
+ FieldDeclaration clonedField = javaFactory.createFieldDeclaration();
+
+ // We construct an access to the "XImpl" type
+ TypeAccess clonedFieldTypeaccess = javaFactory.createTypeAccess();
+ InterfaceDeclaration interfaced = (InterfaceDeclaration) classd.getSuperInterfaces().get(0).getType();
+ clonedFieldTypeaccess.setType(interfaced);
+
+ VariableDeclarationFragment clonedVar = javaFactory.createVariableDeclarationFragment();
+ clonedVar.setName("cloned");
+ clonedVar.setExtraArrayDimensions(0);
+ clonedVar.setProxy(false);
+ clonedVar.setVariablesContainer(clonedField);
+ clonedVar.setOriginalCompilationUnit(classd.getOriginalCompilationUnit());
+
+ Modifier clonedFieldModifier = javaFactory.createModifier();
+ clonedFieldModifier.setStatic(false);
+ clonedFieldModifier.setVisibility(VisibilityKind.PROTECTED);
+
+ clonedField.setType(clonedFieldTypeaccess);
+ clonedField.setModifier(clonedFieldModifier);
+
+ // Preparing a set of the body declarations to remove
+ Set emptyBodies = new HashSet();
+
+ // First pass: analysis and processing the fields
+ for (BodyDeclaration bodyd : classd.getBodyDeclarations()) {
+
+ // If it is a field
+ if (bodyd instanceof FieldDeclaration) {
+ FieldDeclaration fieldd = (FieldDeclaration) bodyd;
+
+ // If it is not static
+ if (!fieldd.getModifier().isStatic()) {
+
+ // We prepare the set of mutable variables (to remove eventually)
+ Set localReadonlys = new HashSet();
+ // And we iterate through the variables
+ for (VariableDeclarationFragment variabled : fieldd.getFragments()) {
+
+ // If it is readonly
+ if (isFieldShareable(variabled)) {
+ processShareableProperty(variabled, copier, classd, clonedVar);
+ localReadonlys.add(variabled);
+ }
+
+ }
+ // We remove from the field the readonly variables
+ fieldd.getFragments().removeAll(localReadonlys);
+ // If the field is empty, it must be removed eventually
+ if (fieldd.getFragments().isEmpty())
+ emptyBodies.add(fieldd);
+
+ }
+ }
+ // Changing constructor
+ if (bodyd instanceof ConstructorDeclaration) {
+ ConstructorDeclaration constructor = (ConstructorDeclaration) bodyd;
+
+ // Changing the name of the constructor
+ constructor.setName(newName);
+
+ // Adding a parameter "cloned"
+ TypeAccess typeaccess = javaFactory.createTypeAccess();
+ typeaccess.setType(interfaced);
+ SingleVariableDeclaration vard = javaFactory.createSingleVariableDeclaration();
+ vard.setType(typeaccess);
+ vard.setName("clonedParam");
+ constructor.getParameters().add(vard);
+
+ // Adding a set of the "cloned" field
+ SingleVariableAccess clonedFieldAccess = javaFactory.createSingleVariableAccess();
+ clonedFieldAccess.setVariable(clonedVar);
+ SingleVariableAccess clonedParamAccess = javaFactory.createSingleVariableAccess();
+ clonedParamAccess.setVariable(vard);
+ Assignment assignment = javaFactory.createAssignment();
+ assignment.setLeftHandSide(clonedFieldAccess);
+ assignment.setRightHandSide(clonedParamAccess);
+ ExpressionStatement assignStatement = javaFactory.createExpressionStatement();
+ assignStatement.setExpression(assignment);
+ constructor.getBody().getStatements().add(assignStatement);
+
+ }
+ }
+
+ // We remove empty fields
+ classd.getBodyDeclarations().removeAll(emptyBodies);
+
+ // Adding cloned field, at last (otherwise it is treated as a RO
+ // variable etc.)
+ classd.getBodyDeclarations().add(0, clonedField);
+
+ }
+
+ /**
+ * Main operation.
+ *
+ * @param srcOutputFolder
+ * @param originalJavaModel
+ * Already processed
+ * @return The original model /!\
+ */
+ public Model transform2PImpl(String srcOutputFolder) {
+
+ // First we make a copy, because we will have to make references to original classes
+ EcoreUtil.Copier copier = new EcoreUtil.Copier();
+ // Model originalModel = (Model) copier.copy(javaModel);
+ Model originalModel = (Model) copier.copy(javaModel);
+ copier.copyReferences();
+
+ // Preparing the set of compilation units to keep (ie. those modified)
+ Set cuToKeep = new HashSet();
+
+ // Creating metamodel package
+ JavaFactory javaFactory = (JavaFactory) Registry.INSTANCE
+ .getEFactory("http://www.eclipse.org/MoDisco/Java/0.2.incubation/java");
+ Package pack = javaFactory.createPackage();
+ pack.setName(tagger.getMetamodelName().toLowerCase() + tagger.getCloningName().toLowerCase());
+ javaModel.getOwnedElements().add(pack);
+
+ // We process each class to process (determined by the preprocessing
+ Log.info("Computed java classes:");
+ Log.plusLevel();
+ for (ClassDeclaration classd : toProcess) {
+
+ ClassTag tag = getTagOfClass(classd);
+
+ if (tag == ClassTag.PARTIALLY_SHAREABLE) {
+
+ processClass(classd, copier);
+
+ Log.info("Computed " + classd.getName() + ".");
+ cuToKeep.add(classd.getOriginalCompilationUnit());
+
+ }
+
+ }
+ Log.minusLevel();
+
+
+ File outputDir = new File(srcOutputFolder + "/" + generateFullyQualifiedName(pack, "/"));
+
+ // Generating the copier
+ if (tagger.mayTagClassesPartShareable())
+ LightCopierGenerator.generate(tagger.getMetamodel(),generateFullyQualifiedName(pack), outputDir, tagger);
+
+ //generateCopierClass(tagger.getMetamodel(),generateFullyQualifiedName(pack), outputDir, tagger);
+
+ TagsGenerator.generateTagsClass(tagger.getMetamodel(),generateFullyQualifiedName(pack), outputDir, tagger);
+
+ //generateTagsClass(pack, srcOutputFolder);
+
+ CloningMaterialClassGenerator.generateCloningMaterialClass(tagger.getMetamodel(),generateFullyQualifiedName(pack), outputDir, tagger);
+
+ //generateCloningMaterialClass(pack, srcOutputFolder);
+
+ for (ClassDeclaration classd : toProcess) {
+ // Then we put it in the target package
+ pack.getOwnedElements().add(classd);
+ classd.setPackage(pack);
+ classd.getOriginalCompilationUnit().setPackage(pack);
+ }
+
+ // Keeping only compilation units that have been written, to only serialize them
+ javaModel.getCompilationUnits().retainAll(cuToKeep);
+
+ // returns the model (useless ? getter better ?)
+ return originalModel;
+ }
+
+ /**
+ * Generates the fully qualified name of a package, with a specific separator between packages. Useful to construct
+ * a path.
+ *
+ * @param pack
+ * The java package.
+ * @param separator
+ * The separator, e.g. "/" or "."
+ * @return The fully qualified name of the package, using the given separator.
+ */
+ private String generateFullyQualifiedName(Package pack, String separator) {
+ if (pack.getPackage() != null)
+ return generateFullyQualifiedName(pack.getPackage(), separator) + separator + pack.getName();
+ else
+ return pack.getName();
+ }
+
+ /**
+ * Generates the java fully qualified name of a pack, using the separator "."
+ *
+ * @param pack
+ * The java package.
+ * @return The fully qualified name of the package, using the separator "."
+ */
+ private String generateFullyQualifiedName(Package pack) {
+ return generateFullyQualifiedName(pack, ".");
+ }
+
+ /*private String generateFullyQualifiedName(InterfaceDeclaration interf) {
+ return generateFullyQualifiedName(interf.getPackage()) + "." + interf.getName();
+ }*/
+
+
+ /**
+ * Creates the mapping from the javamodel to the ecore model
+ */
+ private void computeMapping() {
+ // We navigate through the tagger's metamodel
+ for (Resource ecoreResource : tagger.getMetamodel().getResources()) {
+ // For each package
+ for (EObject object : ecoreResource.getContents()) {
+ if (object instanceof EPackage) {
+ EPackage originalPackage = (EPackage) object;
+ // We find the corresponding java one
+ for (Package javaPackage : javaModel.getOwnedElements()) {
+ // If same name, then process
+ if (javaPackage.getName().equals(originalPackage.getName()))
+ computeMappingPackagedRec(javaPackage, originalPackage);
+ }
+
+ }
+
+ }
+ }
+
+ }
+
+ /**
+ * Recursive operation to create the mapping between two packages
+ *
+ * @param javaPackage
+ * @param originalPackage
+ */
+ private void computeMappingPackagedRec(Package javaPackage, EPackage originalPackage) {
+ // Before all we find the impl package in the java package
+ Package impl = null;
+ for (Package javaSubP : javaPackage.getOwnedPackages()) {
+ if (javaSubP.getName().equals("impl")) {
+ impl = javaSubP;
+ break;
+ }
+ }
+
+ // For each eclass of the original package
+ for (EClassifier classifier : originalPackage.getEClassifiers()) {
+ if (classifier instanceof EClass) {
+ EClass eclass = (EClass) classifier;
+ // We search the java implementation and we store in the map
+ for (AbstractTypeDeclaration typed : impl.getOwnedElements()) {
+ if (typed instanceof ClassDeclaration && typed.getName().equals((eclass.getName() + "Impl"))) {
+ ClassDeclaration classd = (ClassDeclaration) typed;
+ classesMapping.put((InterfaceDeclaration) classd.getSuperInterfaces().get(0).getType(), eclass);
+ wholeMetamodel.add(classd);
+ ClassTag tag = getTagOfClass(classd);
+ if (tag == ClassTag.PARTIALLY_SHAREABLE) {
+ toProcess.add(classd);
+ }
+ computeMappingInClass(classd, eclass);
+ break;
+ }
+ }
+
+ }
+ }
+
+ // Then for each subpackage in the original metamodel package
+ for (EPackage subP : originalPackage.getESubpackages()) {
+ // We look for the corresponding java one
+ for (Package javaSubP : javaPackage.getOwnedPackages()) {
+ if (javaSubP.getName().equals(subP.getName())) {
+ // And we recursively process the package
+ computeMappingPackagedRec(javaSubP, subP);
+ }
+ }
+ }
+ }
+
+ /**
+ * Creates the mapping between the properties of a java class and its ecore metaclass.
+ *
+ * @param javaClass
+ * The java class.
+ * @param originalClass
+ * The ecore class.
+ */
+ private void computeMappingInClass(ClassDeclaration javaClass, EClass originalClass) {
+ for (EStructuralFeature prop : originalClass.getEAllStructuralFeatures()) {
+ for (BodyDeclaration bodyd : javaClass.getBodyDeclarations()) {
+ // If it is a field
+ if (bodyd instanceof FieldDeclaration) {
+ FieldDeclaration fieldd = (FieldDeclaration) bodyd;
+ // If it is not static
+ if (!fieldd.getModifier().isStatic()) {
+ // And we iterate through the variables
+ for (VariableDeclarationFragment variabled : fieldd.getFragments()) {
+ // If same name, then mapping
+ if (variabled.getName().toLowerCase().equals(prop.getName().toLowerCase())) {
+ propertiesMapping.put(variabled, prop);
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/moclodash/fr.inria.diverse.cloning.materialgenerator/src/fr/inria/diverse/cloning/materialgenerator/generators/LightCopierGenerator.java b/moclodash/fr.inria.diverse.cloning.materialgenerator/src/fr/inria/diverse/cloning/materialgenerator/generators/LightCopierGenerator.java
new file mode 100644
index 0000000000000000000000000000000000000000..33512d5f01c8f529fc99affe0e9eea8375be3e74
--- /dev/null
+++ b/moclodash/fr.inria.diverse.cloning.materialgenerator/src/fr/inria/diverse/cloning/materialgenerator/generators/LightCopierGenerator.java
@@ -0,0 +1,127 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Université de Rennes 1.
+ * 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:
+ * Erwan Bousse - initial API and implementation
+ ******************************************************************************/
+package fr.inria.diverse.cloning.materialgenerator.generators;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.util.Set;
+
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.resource.ResourceSet;
+
+import fr.inria.diverse.cloning.materialgenerator.tagger.Tagger;
+import fr.inria.diverse.cloning.runtime.common.ClassTag;
+import fr.inria.diverse.cloning.runtime.emfextension.impl.LooseCopier;
+import fr.inria.diverse.cloning.runtime.util.EcoreHelper;
+
+public class LightCopierGenerator {
+
+ /**
+ * Generates a Copier that can create light clones.
+ *
+ * @param pack
+ * The package in which all partial implementations are put.
+ * @param srcOutputFolder
+ * The folder in which the clas must be written.
+ */
+ public static void generate(ResourceSet metamodel, String javapackagename, File outputDir, Tagger tagger) {
+
+ // Computing the class name
+ String className = tagger.getMetamodelName() + tagger.getCloningName() + Constants.COPIER_SUFFIX;
+ className = Character.toUpperCase(className.charAt(0)) + className.substring(1);
+
+ try {
+ // Preparing the output file
+ // File outputDir = new File(srcOutputFolder + "/" + generateFullyQualifiedName(pack, "/"));*/
+
+ outputDir.mkdirs();
+ File outputFile = new File(outputDir, className + ".java");
+ outputFile.createNewFile();
+ PrintStream printer = new PrintStream(outputFile);
+
+ // Package header
+ printer.println("package " + javapackagename + ";\n");
+
+ // Imports not metamodel dependent
+ String imports = "import org.eclipse.emf.ecore.EObject;\n";
+ imports += "import " + LooseCopier.class.getCanonicalName() + ";\n";
+
+ // Class declaration
+ String classdef = "@SuppressWarnings(\"serial\")\n";
+ classdef += "public class " + className + " extends " + LooseCopier.class.getSimpleName() + " {\n";
+
+ // Method declaration
+ // classdef += "@Override\n";
+ classdef += "protected EObject createCopy(EObject eObject) {\n";
+
+ // For each class
+ boolean firstIf = true;
+ boolean hasShareable = false;
+ Set eClasses = EcoreHelper.findEClasses(metamodel);
+ for (EClass c : eClasses) {
+
+ if (tagger.getTagOfEClass(c) == ClassTag.PARTIALLY_SHAREABLE) {
+ hasShareable = true;
+ imports += "import " + EcoreHelper.computeFullyQualifiedName(c) + ";\n";
+
+ // We generate its if/elseif lines
+ if (!firstIf) {
+ classdef += "else\n";
+ firstIf = false;
+ }
+ classdef += "if (eObject instanceof " + c.getName() + ")\n";
+ classdef += "return new " + c.getName() + tagger.getSuffix() + "((" + c.getName() + ")"
+ + "eObject);\n";
+
+ }
+
+ else if (tagger.getTagOfEClass(c) == ClassTag.COMPLETELY_SHAREABLE) {
+ hasShareable = true;
+ imports += "import " + EcoreHelper.computeFullyQualifiedName(c) + ";\n";
+
+ // We generate its if/elseif lines
+ if (!firstIf) {
+ classdef += "else\n";
+ firstIf = false;
+ }
+ classdef += "if (eObject instanceof " + c.getName() + ")\n";
+ classdef += "return eObject;\n";
+
+ }
+
+
+ }
+
+ // Default case: call to the super method
+ if (hasShareable) {
+ classdef += "else\n";
+ }
+
+ classdef += "return super.createCopy(eObject);\n";
+
+ // end method declaration
+ classdef += "}\n";
+ // end class declaration
+ classdef += "}\n";
+
+ // Then ultimately we put all this stuff in a file
+ printer.println(imports);
+ printer.println(classdef);
+ printer.close();
+ } catch (IOException e) {
+ System.err.println("Impossible to write copier " + className + "!");
+ e.printStackTrace();
+ }
+
+ }
+
+}
diff --git a/moclodash/fr.inria.diverse.cloning.materialgenerator/src/fr/inria/diverse/cloning/materialgenerator/generators/ManifestEditor.java b/moclodash/fr.inria.diverse.cloning.materialgenerator/src/fr/inria/diverse/cloning/materialgenerator/generators/ManifestEditor.java
new file mode 100644
index 0000000000000000000000000000000000000000..821f1381fed05812f977415c243f7d249c2a2c6c
--- /dev/null
+++ b/moclodash/fr.inria.diverse.cloning.materialgenerator/src/fr/inria/diverse/cloning/materialgenerator/generators/ManifestEditor.java
@@ -0,0 +1,149 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Université de Rennes 1.
+ * 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:
+ * Erwan Bousse - initial API and implementation
+ ******************************************************************************/
+package fr.inria.diverse.cloning.materialgenerator.generators;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.StringReader;
+import java.util.jar.Attributes.Name;
+import java.util.jar.Manifest;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+
+/*****************************************************************************
+ * Copyright (c) 2011 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: Camille Letavernier (CEA LIST) camille.letavernier@cea.fr - Initial API and implementation
+ *
+ *
+ * from http://dev.eclipse.org/svnroot/modeling/org.eclipse.mdt.papyrus/branches/0.8.X-EYY/plugins/configurationTK/org.
+ * eclipse.papyrus.customization/src/org/eclipse/papyrus/customization/plugin/ManifestEditor.java
+ *
+ *****************************************************************************/
+public class ManifestEditor {
+
+ private IProject project;
+
+ private IFile manifestFile;
+
+ private Manifest manifest;
+
+ public ManifestEditor(IProject project) throws IOException, CoreException {
+ this.project = project;
+ manifestFile = getManifestFile();
+
+ manifest = new Manifest(manifestFile.getContents());
+ }
+
+ public void addDependency(String dependency) {
+ addDependency(dependency, null);
+ }
+
+ public void addDependency(String dependency, String version) {
+ Name rqBundle = new Name("Require-Bundle"); //$NON-NLS-1$
+ String requireBundle = manifest.getMainAttributes().getValue(rqBundle);
+
+ // TODO : Improve the detection of existing dependency
+ // If a.b.c exists, then a.b cannot be added (Because it is already contained)
+ // Moreover, the Manifest allows newlines anywhere (Including in the
+ // middle of a word) : check if these newlines appear in this map,
+ // or if they have already been parsed. If the manifest value is copied as-is in the map,
+ // then we need to take care of newlines when parsing it
+
+ if (requireBundle == null) {
+ requireBundle = dependency;
+ if (version != null) {
+ requireBundle += ";" + version; //$NON-NLS-1$
+ }
+ } else if (!requireBundle.contains(dependency)) {
+ requireBundle += "," + dependency; //$NON-NLS-1$
+ if (version != null) {
+ requireBundle += ";" + version; //$NON-NLS-1$
+ }
+ }
+
+ manifest.getMainAttributes().put(rqBundle, requireBundle);
+ }
+
+ public void setValue(String key, String value) {
+ setValue(key, "", value); //$NON-NLS-1$
+ }
+
+ public void setSingleton(boolean singleton) {
+ String value = manifest.getMainAttributes().getValue("bundle-symbolicName");
+ String[] directives = value.split(";");
+
+ if (directives.length == 0) {
+ return; // This should not happen if the Manifest is well-formed
+ } else {
+ value = directives[0];
+ boolean isDefined = false;
+ for (int i = 1; i < directives.length; i++) {
+ String directive = directives[i];
+ if (directive.startsWith("singleton:=")) {
+ directive = "singleton:=" + singleton;
+ isDefined = true;
+ }
+ value += ";" + directive;
+ }
+ if (!isDefined) {
+ value += ";singleton:=" + singleton;
+ }
+ }
+
+ manifest.getMainAttributes().putValue("bundle-symbolicName", value);
+ }
+
+ public void setValue(String key, String name, String value) {
+ manifest.getAttributes(key).put(name, value);
+ }
+
+ public void removeValue(String key, String value) {
+
+ }
+
+ public void removeValue(String key) {
+ manifest.getAttributes(key).remove(key);
+ }
+
+ private IFile getManifestFile() {
+ IFile manifest = project.getFile("META-INF/MANIFEST.MF"); //$NON-NLS-1$
+ if (manifest.exists()) {
+ return manifest;
+ }
+
+ // TODO : Manifest creation not supported
+ return null;
+ }
+
+ public void save() throws IOException, CoreException {
+
+ ByteArrayOutputStream os = new ByteArrayOutputStream();
+
+ manifest.write(os);
+
+ final StringReader reader = new StringReader(os.toString("UTF-8")); //$NON-NLS-1$
+ manifestFile.setContents(new InputStream() {
+
+ @Override
+ public int read() throws IOException {
+ return reader.read();
+ }
+ }, true, true, null);
+ }
+}
diff --git a/moclodash/fr.inria.diverse.cloning.materialgenerator/src/fr/inria/diverse/cloning/materialgenerator/generators/PImplGenerator.java b/moclodash/fr.inria.diverse.cloning.materialgenerator/src/fr/inria/diverse/cloning/materialgenerator/generators/PImplGenerator.java
new file mode 100644
index 0000000000000000000000000000000000000000..015877d6f805f03a5449aef14f28958844e34cf4
--- /dev/null
+++ b/moclodash/fr.inria.diverse.cloning.materialgenerator/src/fr/inria/diverse/cloning/materialgenerator/generators/PImplGenerator.java
@@ -0,0 +1,220 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Université de Rennes 1.
+ * 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:
+ * Erwan Bousse - initial API and implementation
+ ******************************************************************************/
+package fr.inria.diverse.cloning.materialgenerator.generators;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Set;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.gmt.modisco.java.Model;
+import org.eclipse.gmt.modisco.java.generation.files.GenerateJavaExtended;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.modisco.infra.discovery.core.exception.DiscoveryException;
+import org.eclipse.modisco.java.discoverer.DiscoverJavaModelFromJavaProject;
+
+import fr.inria.diverse.cloning.materialgenerator.tagger.Tagger;
+import fr.inria.diverse.cloning.runtime.util.Log;
+
+public class PImplGenerator {
+
+ //private static final String FAKE_PROJECT_NAME = "fakeProject";
+
+ /*public static void generate(Set serializedMetamodel, String metamodelname, File outputFolder, Tagger tagger, boolean readonlyWarningsInSetters) {
+ try {
+ // Creating a fake eclipse project in which the code will be generated
+ File tmpDir = File.createTempFile(FAKE_PROJECT_NAME, "");
+ tmpDir.delete();
+ tmpDir.mkdir();
+ IProjectDescription description = ResourcesPlugin.getWorkspace().newProjectDescription(FAKE_PROJECT_NAME);
+ description.setLocationURI(java.net.URI.create(tmpDir.getAbsolutePath()));
+ IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(description.getName());
+ project.delete(true, true, null);
+ project.create(description, null);
+ project.open(null);
+
+ project.delete(false, true, null);
+ project.create(description, null);
+
+ generate(serializedMetamodel, metamodelname, project, tagger, readonlyWarningsInSetters);
+
+ // Copying everything from the fake project folder in the output folder
+ outputFolder.mkdirs();
+ Copy.copyRecursive(tmpDir.toPath(), outputFolder.toPath());
+
+ } catch (CoreException e) {
+ // TODO Bloc catch généré automatiquement
+ e.printStackTrace();
+ } catch (IOException e) {
+ // TODO Bloc catch généré automatiquement
+ e.printStackTrace();
+ }
+
+ }*/
+
+ public static void generate(String metamodelname, IProject emfProject, Tagger tagger,
+ boolean readonlyWarningsInSetters) {
+
+
+ try {
+ emfProject.open(null);
+
+ IJavaProject javaProject = JavaCore.create(emfProject);
+
+ // Discovering the model from the project
+ DiscoverJavaModelFromJavaProject discoverer = new DiscoverJavaModelFromJavaProject();
+ discoverer.discoverElement(javaProject, new NullProgressMonitor());
+
+ // Accessing the obtained model
+ Resource result = discoverer.getTargetModel();
+ Model javaModel = (Model) result.getContents().get(0);
+
+ // Preparing outputdir for code generation
+ File projectFolder = new File(emfProject.getRawLocationURI().toString());
+ File outputSrc = new File(projectFolder, "src");
+ outputSrc.mkdirs();
+
+ // Calling the partial implementations transformer with one tagger
+ Model originalModel = javaModel;
+
+ originalModel = new EMFImpl2PImpl(originalModel, tagger, readonlyWarningsInSetters).transform2PImpl(outputSrc.getAbsolutePath());
+
+
+ // Generating the code from the obtained model
+ GenerateJavaExtended javaGenerator = new GenerateJavaExtended(javaModel, outputSrc, new ArrayList