blob: fd7518a08485fa1162cd83b325720c0e259296b8 [file] [log] [blame]
package org.eclipse.emf.refactor.smells.generator.managers;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.emf.codegen.jet.JETEmitter;
import org.eclipse.emf.codegen.jet.JETException;
import org.eclipse.emf.codegen.util.CodeGenUtil;
import org.eclipse.emf.refactor.smells.generator.Activator;
import org.eclipse.emf.refactor.smells.generator.core.MetricBasedModelSmellInfo;
import org.eclipse.emf.refactor.smells.generator.core.ModelSmellInfo;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.JavaCore;
import org.osgi.framework.Bundle;
public class SmellGenerationManager {
private static SmellGenerationManager instance;
private static final String JAVA_TEMPLATE_CLASS_NAME = "JavaFinderClassTemplate";
private static final String METRIC_TEMPLATE_CLASS_NAME = "MetricBasedFinderClassTemplate";
protected static final String TEMPLATE_DIR = "/templates";
private static final String SOURCE_DIR = "/src/";
protected static final String TEMPLATE_FILE_EXTENSION = ".javajet";
private static final String JAVA_FILE_EXTENSION = ".java";
protected static final String PLUGINSPATH = Platform.getInstallLocation().getURL().getPath() + "plugins/";
protected static final String BUNDLEVERSION = "Bundle-Version";
protected static String templateDirectory;
protected static List<IClasspathEntry> classpathEntries;
protected SmellGenerationManager() {
templateDirectory = setTemplateDirectory();
classpathEntries = setClassPathEntries();
System.out.println("GenerationManager initialized!");
}
protected List<IClasspathEntry> setClassPathEntries() {
ArrayList<IClasspathEntry> cpe = new ArrayList<IClasspathEntry>();
Bundle bundle = Platform.getBundle(Activator.PLUGIN_ID);
// add org.eclipse.emf.refactor.smells.generator to class path
String version = (String) bundle.getHeaders().get(BUNDLEVERSION);
cpe.add(JavaCore.newLibraryEntry(new Path(PLUGINSPATH
+ Activator.PLUGIN_ID + "_" + version + ".jar"), null, null));
// add org.eclipse.emf.refactor.smells to class path
bundle = Platform.getBundle(org.eclipse.emf.refactor.smells.Activator.PLUGIN_ID);
version = (String) bundle.getHeaders().get(BUNDLEVERSION);
cpe.add(JavaCore.newLibraryEntry(new Path(PLUGINSPATH +
org.eclipse.emf.refactor.smells.Activator.PLUGIN_ID + "_" + version + ".jar"), null, null));
return cpe;
}
public static SmellGenerationManager getInstance() {
if (instance == null) {
instance = new SmellGenerationManager();
}
return instance;
}
public static void createNewModelSmell(IProgressMonitor monitor,
ModelSmellInfo modelSmellInfo, IProject newSmellTargetProject) {
DependenciesManager.updateDependencies(modelSmellInfo);
createFinderClass(monitor, modelSmellInfo);
XMLPluginFileManager.createModelSmellEntry(modelSmellInfo.getProjectPath(),
modelSmellInfo.getName(), modelSmellInfo.getDescription(),
modelSmellInfo.getMetamodel(), modelSmellInfo.getId(),
modelSmellInfo.getPackage()+"."+modelSmellInfo.getClassName());
try {
newSmellTargetProject.refreshLocal(IProject.DEPTH_INFINITE, monitor);
newSmellTargetProject.refreshLocal(IProject.DEPTH_INFINITE, monitor);
} catch (CoreException e) {
e.printStackTrace();
}
}
private static void createFinderClass(IProgressMonitor monitor,
ModelSmellInfo modelSmellInfo) {
String generatedCode = "";
String templateName = "";
if(modelSmellInfo instanceof MetricBasedModelSmellInfo){
templateName = METRIC_TEMPLATE_CLASS_NAME;
} else {
templateName = JAVA_TEMPLATE_CLASS_NAME;
}
try {
generatedCode = generateCode(monitor, templateName, modelSmellInfo);
saveCode(monitor, generatedCode, modelSmellInfo);
} catch (JETException e) {
e.printStackTrace();
} catch (CoreException e) {
e.printStackTrace();
}
}
protected static void saveCode(IProgressMonitor monitor, String content, ModelSmellInfo modelSmellInfo) throws CoreException, JETException {
IContainer container = findOrCreatePackage(monitor, modelSmellInfo);
if (container == null) {
throw new JETException("Could not find or create container for package " + modelSmellInfo.getPackage() + " in " + modelSmellInfo.getProjectName());
}
IFile file = container.getFile(new Path(modelSmellInfo.getClassName() + JAVA_FILE_EXTENSION));
System.out.println("saving code into: "+file.getLocation());
InputStream inputStream = new ByteArrayInputStream(content.getBytes());
if (!file.exists()) {
file.create(inputStream, false, monitor);
} else {
container.refreshLocal(1, monitor);
file.setContents(inputStream, true, false, monitor);
}
}
private static IContainer findOrCreatePackage(IProgressMonitor progressMonitor, ModelSmellInfo modelSmellInfo) throws CoreException {
IPath outputPath = new Path(modelSmellInfo.getProjectName() + SOURCE_DIR + modelSmellInfo.getPackage().replace('.', '/'));
IProgressMonitor subMonitor = new SubProgressMonitor(progressMonitor, 1);
IPath localLocation = null;
IContainer container = CodeGenUtil.EclipseUtil.findOrCreateContainer(outputPath, true, localLocation, subMonitor);
return container;
}
@SuppressWarnings("finally")
private static String generateCode(IProgressMonitor monitor, String template, ModelSmellInfo modelSmellInfo) {
String templatePath = templateDirectory + template + TEMPLATE_FILE_EXTENSION;
ClassLoader classLoader = modelSmellInfo.getClass().getClassLoader();
JETEmitter jetEmitter = new JETEmitter(templatePath, classLoader);
jetEmitter.getClasspathEntries().addAll(classpathEntries);
String result = "";
IProgressMonitor subMonitor = new SubProgressMonitor(monitor, 1);
try {
result = jetEmitter.generate(subMonitor, new Object[] {modelSmellInfo});
} catch (JETException e) {
result = e.getMessage();
e.printStackTrace();
} finally {
System.out.println(result);
return result;
}
}
private String setTemplateDirectory() {
String directory = "";
final Bundle bundle = Activator.getDefault().getBundle();
try {
directory = FileLocator.toFileURL(bundle.getEntry(TEMPLATE_DIR)).getFile();
} catch (final IOException e) {
e.printStackTrace();
}
return directory;
}
}