Commit ce354e76 authored by Erwan Bousse's avatar Erwan Bousse

Major improvement: now inheritance and abstract classes and interfaces are...

Major improvement: now inheritance and abstract classes and interfaces are taken into account. Also error messages are now displayed when generating cloning material
parent eee4fcef
......@@ -41,7 +41,8 @@ public class LightCopierGenerator {
try {
// Preparing the output file
// File outputDir = new File(srcOutputFolder + "/" + generateFullyQualifiedName(pack, "/"));*/
// File outputDir = new File(srcOutputFolder + "/" +
// generateFullyQualifiedName(pack, "/"));*/
outputDir.mkdirs();
File outputFile = new File(outputDir, className + ".java");
......@@ -69,35 +70,38 @@ public class LightCopierGenerator {
Set<EClass> eClasses = EcoreHelper.findEClasses(metamodel);
for (EClass c : eClasses) {
if (tagger.getTagOfEClass(c) == ClassTag.PARTIALLY_SHAREABLE) {
hasShareable = true;
imports += "import " + EcoreHelper.computeFullyQualifiedName(c) + ";\n";
if (!c.isAbstract() && !c.isInterface()) {
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";
// 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;
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";
}
classdef += "if (eObject instanceof " + c.getName() + ")\n";
classdef += "return eObject;\n";
}
}
......
......@@ -30,8 +30,8 @@ import fr.inria.diverse.cloning.runtime.util.Log;
public class TagsGenerator {
/**
* Generates a java class implementing the MetamodelTags interface, to retrieve at runtine the generate tags of the
* metamodel classes.
* 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.
......@@ -77,21 +77,20 @@ public class TagsGenerator {
boolean firstIf = true;
Set<EClass> eClasses = EcoreHelper.findEClasses(metamodel);
for (EClass c : eClasses) {
if (!c.isInterface()) {
//imports += "import " + EcoreHelper.computeFullyQualifiedName(c) + ";\n";
// We generate its if/elseif lines
if (!firstIf) {
classdef += "else\n";
firstIf = false;
}
String packageInterfaceName = EcoreHelper.computeFullyQualifiedName(c.getEPackage()) + "."
+ CodeGeneration.firstCharUp(c.getEPackage().getName()) + "Package";
// We generate its if/elseif lines
if (!firstIf) {
classdef += "else\n";
firstIf = false;
}
classdef += "if (eClass.equals(" + packageInterfaceName + ".eINSTANCE.get" + c.getName() + "()))\n";
classdef += "return " + ClassTag.class.getSimpleName() + "." + tagger.getTagOfEClass(c) + ";\n";
String packageInterfaceName = EcoreHelper.computeFullyQualifiedName(c.getEPackage()) + "."
+ CodeGeneration.firstCharUp(c.getEPackage().getName()) + "Package";
classdef += "if (eClass.equals(" + packageInterfaceName + ".eINSTANCE.get" + c.getName() + "()))\n";
classdef += "return " + ClassTag.class.getSimpleName() + "." + tagger.getTagOfEClass(c) + ";\n";
}
}
// Default case: call to the super method
......@@ -115,22 +114,23 @@ public class TagsGenerator {
// For each class that led to a pimpl
boolean firstIf2 = true;
for (EClass c : eClasses) {
if (!c.isInterface()) {
for (EStructuralFeature prop : c.getEStructuralFeatures()) {
for (EStructuralFeature prop : c.getEStructuralFeatures()) {
// We generate its if/elseif lines
if (!firstIf2) {
classdef += "else\n";
firstIf2 = false;
}
String packageInterfaceName = EcoreHelper.computeFullyQualifiedName(c.getEPackage()) + "."
+ CodeGeneration.firstCharUp(c.getEPackage().getName()) + "Package";
// We generate its if/elseif lines
if (!firstIf2) {
classdef += "else\n";
firstIf2 = false;
}
classdef += "if (prop.equals(" + packageInterfaceName + ".eINSTANCE.get" + c.getName() + "_"
+ CodeGeneration.firstCharUp(prop.getName()) + "()))\n";
classdef += "return " + String.valueOf(tagger.isPropertyShareable(prop)) + ";\n";
String packageInterfaceName = EcoreHelper.computeFullyQualifiedName(c.getEPackage()) + "."
+ CodeGeneration.firstCharUp(c.getEPackage().getName()) + "Package";
classdef += "if (prop.equals(" + packageInterfaceName + ".eINSTANCE.get" + c.getName() + "_"
+ CodeGeneration.firstCharUp(prop.getName()) + "()))\n";
classdef += "return " + String.valueOf(tagger.isPropertyShareable(prop)) + ";\n";
}
}
}
// Default case
......@@ -139,8 +139,7 @@ public class TagsGenerator {
// end isPropertyMutable method declaration
classdef += "}\n";
// metrics methods declaration
classdef += "public double getShareableClassesRatio() {\n";
classdef += "return " + CloningMetrics.computeShareableClassesRatio(metamodel, tagger) + ";\n";
......@@ -152,10 +151,12 @@ public class TagsGenerator {
classdef += "return " + CloningMetrics.computeIsolatedShareablePropertiesRatio(metamodel, tagger) + ";\n";
classdef += "}\n";
classdef += "public double getShareablePropertiesInPartShareableClassesDensity() {\n";
classdef += "return " + CloningMetrics.computeShareablePropertiesInPartShareableClassesDensity(metamodel, tagger)+ ";\n";
classdef += "return "
+ CloningMetrics.computeShareablePropertiesInPartShareableClassesDensity(metamodel, tagger) + ";\n";
classdef += "}\n";
classdef += "public double getShareablePropertiesInShareableClassesDensity() {\n";
classdef += "return " + CloningMetrics.computeShareablePropertiesInShareableClassesDensity(metamodel, tagger)+ ";\n";
classdef += "return "
+ CloningMetrics.computeShareablePropertiesInShareableClassesDensity(metamodel, tagger) + ";\n";
classdef += "}\n";
// end metrics methods declaration
......
......@@ -19,7 +19,9 @@ import java.util.Set;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Status;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EcorePackage;
......@@ -46,7 +48,8 @@ import fr.inria.diverse.cloning.runtime.util.Log;
public class Start {
public static void start(Set<File> ecoreFiles, String metamodelName, IJavaProject javaProject, boolean emf) {
public static void start(Set<File> ecoreFiles, String metamodelName, IJavaProject javaProject, boolean emf)
throws CoreException {
Log.info("Starting Cloning material generator");
try {
......@@ -56,7 +59,8 @@ public class Start {
rs = EMFCodeGenerator.generate(ecoreFiles, metamodelName, javaProject.getProject());
else {
// Loading some ecore files in a resource set (= considered metamodel)
// Loading some ecore files in a resource set (= considered
// metamodel)
EcoreResourceFactoryImpl fact = new EcoreResourceFactoryImpl();
if (!EPackage.Registry.INSTANCE.containsKey(EcorePackage.eNS_URI)) {
EPackage.Registry.INSTANCE.put(EcorePackage.eNS_URI, EcorePackage.eINSTANCE);
......@@ -71,7 +75,7 @@ public class Start {
Collection<Tagger> taggers = Arrays.asList(new DeepCloningTagger(rs, metamodelName),
new ShareFieldsOnlyTagger(rs, metamodelName), new ShareObjOnlyTagger(rs, metamodelName),
new ShareAllTagger(rs, metamodelName));
// Discovering the model from the project
DiscoverJavaModelFromJavaProject discoverer = new DiscoverJavaModelFromJavaProject();
......@@ -84,7 +88,8 @@ public class Start {
// Getting the absolute path of the folder
File emfProjectFolder = javaProject.getProject().getLocation().toFile();
// String srcOutputFolder = "/home/ebousse/Dev/modelCloning/emf/SomeMetamodel/src";
// String srcOutputFolder =
// "/home/ebousse/Dev/modelCloning/emf/SomeMetamodel/src";
String srcOutputFolder = new File(emfProjectFolder, "src").getAbsolutePath();
// Calling the partial implementations transformer with one tagger
......@@ -97,18 +102,6 @@ public class Start {
javaGenerator.doGenerate(null);
toProcess = brandNew;
}
//new EMFImpl2PImpl(originalModel, tagger2, true).transform2PImpl(srcOutputFolder);
// // Generating the code from the obtained model
// GenerateJavaExtended javaGenerator = new GenerateJavaExtended(javaModel, new File(srcOutputFolder),
// new ArrayList<Object>());
// javaGenerator.doGenerate(null);
//
// // Generating the code from the obtained model
// GenerateJavaExtended javaGenerator2 = new GenerateJavaExtended(originalModel, new File(srcOutputFolder),
// new ArrayList<Object>());
// javaGenerator2.doGenerate(null);
// Adding a dependency in the manifest
ManifestEditor manEdit = new ManifestEditor(javaProject.getProject());
......@@ -119,18 +112,11 @@ public class Start {
// Done
Log.info("Done !");
} catch (DiscoveryException e) {
// TODO Bloc catch généré automatiquement
e.printStackTrace();
} catch (IOException e) {
// TODO Bloc catch généré automatiquement
e.printStackTrace();
} catch (EMFGenerationException e) {
// TODO Bloc catch généré automatiquement
e.printStackTrace();
} catch (CoreException e) {
// TODO Bloc catch généré automatiquement
} catch (Exception e) {
e.printStackTrace();
IStatus status = new Status(IStatus.ERROR, "fr.inria.diverse.cloning.materialgenerator", e.getMessage());
throw new CoreException(status);
}
}
}
......@@ -29,7 +29,8 @@ import fr.inria.diverse.cloning.runtime.util.Log;
public abstract class AbstractTagger implements Tagger {
/**
* Final result of the algorithm, with a tag for each class concerning its "mutability".
* Final result of the algorithm, with a tag for each class concerning its
* "mutability".
*/
protected Map<EClass, ClassTag> classesTags;
......@@ -38,7 +39,6 @@ public abstract class AbstractTagger implements Tagger {
protected ResourceSet metamodel;
protected String metamodelname;
@Override
public String getMetamodelName() {
......@@ -54,14 +54,17 @@ public abstract class AbstractTagger implements Tagger {
for (Resource resource : metamodel.getResources())
for (Iterator<EObject> i = resource.getAllContents(); i.hasNext();) {
EObject current = i.next();
if (current instanceof EClass)
classesTags.put((EClass) current, null);
if (current instanceof EClass) {
EClass currentEClass = (EClass) current;
if (!currentEClass.isInterface())
classesTags.put((EClass) current, null);
}
}
recomputeTags();
}
public AbstractTagger(Set<Resource> metamodel, String metamodelname) {
}
protected boolean isMutable(EClass c) {
......@@ -70,17 +73,14 @@ public abstract class AbstractTagger implements Tagger {
}
protected static boolean isPropertyDesignedMutable(EStructuralFeature f) {
//return f.getName().endsWith("_m");
// return f.getName().endsWith("_m");
return EcoreHelper.isPropertyDesignedMutable(f);
}
protected enum PropertiesMutability {
allMutable, someMutable, noneMutable
}
@Override
public ClassTag getTagOfEClass(EClass c) {
if (classesTags.containsKey(c)) {
......@@ -94,7 +94,6 @@ public abstract class AbstractTagger implements Tagger {
}
@Override
public ResourceSet getMetamodel() {
return metamodel;
......
......@@ -137,8 +137,8 @@ public class ShareAllTagger extends AbstractTagger {
}
/**
* To me used as soon as some SCC is found by the Tarjan algorithm. Will iterate over all classes of the SCC, and
* tags them for mutability.
* To be used as soon as some SCC is found by the Tarjan algorithm. Will iterate over all classes of the SCC, and
* tag them for mutability.
*
* @param scc
* A StronglyConnectedComponent freshly computed in Tarjan.
......
......@@ -10,13 +10,9 @@
******************************************************************************/
package fr.inria.diverse.cloning.materialgenerator.tagger.impl;
import java.util.Iterator;
import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import fr.inria.diverse.cloning.runtime.common.ClassTag;
......@@ -28,37 +24,32 @@ public class ShareFieldsOnlyTagger extends AbstractTagger {
super(metamodel, metamodelname);
}
@Override
public void recomputeTags() {
Log.info("Tagging with ShareFieldsOnlyTagger.");
for (Resource res : metamodel.getResources()) {
for (Iterator<EObject> i = res.getAllContents(); i.hasNext();) {
EObject next = i.next();
if (next instanceof EClass) {
EClass c = (EClass) next;
boolean hasReadonlys = false;
// First attributes
for (EAttribute att : c.getEAllAttributes()) {
if (isPropertyDesignedMutable(att))
propertiesTags.put(att, false);
else {
propertiesTags.put(att, true);
hasReadonlys = true;
}
}
// Then references, all mutable
for (EReference ref : c.getEAllReferences()) {
propertiesTags.put(ref, false);
}
if (hasReadonlys)
classesTags.put(c, ClassTag.PARTIALLY_SHAREABLE);
else
classesTags.put(c, ClassTag.NOT_SHAREABLE);
for (EClass next : classesTags.keySet()) {
EClass c = (EClass) next;
boolean hasReadonlys = false;
// First attributes
for (EAttribute att : c.getEAllAttributes()) {
if (isPropertyDesignedMutable(att))
propertiesTags.put(att, false);
else {
propertiesTags.put(att, true);
hasReadonlys = true;
}
}
// Then references, all mutable
for (EReference ref : c.getEAllReferences()) {
propertiesTags.put(ref, false);
}
if (hasReadonlys)
classesTags.put(c, ClassTag.PARTIALLY_SHAREABLE);
else
classesTags.put(c, ClassTag.NOT_SHAREABLE);
}
Log.info("Computed mutabilities:");
Log.plusLevel();
for (EClass c : classesTags.keySet()) {
......@@ -83,7 +74,6 @@ public class ShareFieldsOnlyTagger extends AbstractTagger {
return "ShareFieldsOnly";
}
@Override
public boolean mayTagClassesPartShareable() {
return true;
......
......@@ -56,7 +56,7 @@ public class CodeGeneration {
// instantiate the default code formatter with the given options
final CodeFormatter codeFormatter = ToolFactory.createCodeFormatter(options);
final TextEdit edit = codeFormatter.format(CodeFormatter.K_COMPILATION_UNIT, // format a compilation unit
source, // source to format
0, // starting position
......@@ -64,7 +64,6 @@ public class CodeGeneration {
0, // initial indentation
System.getProperty("line.separator") // line separator
);
IDocument document = new Document(source);
try {
edit.apply(document);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment