blob: 63e5fd526202bdb395c127680b455b029fe22a54 [file] [log] [blame]
package org.eclipse.emf.henshin.giraph;
import java.io.ByteArrayInputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.eclipse.ant.core.AntRunner;
import org.eclipse.core.resources.ICommand;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectDescription;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.IncrementalProjectBuilder;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.core.runtime.jobs.IJobChangeEvent;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.core.runtime.jobs.JobChangeAdapter;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.henshin.giraph.templates.BuildJarLaunchTemplate;
import org.eclipse.emf.henshin.giraph.templates.CompileXmlTemplate;
import org.eclipse.emf.henshin.giraph.templates.GetLibsXmlTemplate;
import org.eclipse.emf.henshin.giraph.templates.GiraphRuleTemplate;
import org.eclipse.emf.henshin.giraph.templates.HenshinUtilTemplate;
import org.eclipse.emf.henshin.giraph.templates.InstallHadoopXmlTemplate;
import org.eclipse.emf.henshin.giraph.templates.LaunchConfTemplate;
import org.eclipse.emf.henshin.giraph.templates.LaunchEnvXmlTemplate;
import org.eclipse.emf.henshin.giraph.templates.LaunchXmlTemplate;
import org.eclipse.emf.henshin.giraph.templates.PomXmlTemplate;
import org.eclipse.emf.henshin.model.Rule;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.launching.IVMInstall;
import org.eclipse.jdt.launching.JavaRuntime;
public class GiraphGenerator extends GiraphValidator {
protected int refreshJobs = 0;
/**
* Default constructor.
*/
public GiraphGenerator() {
Job.getJobManager().addJobChangeListener(new JobChangeAdapter() {
@Override
public void scheduled(IJobChangeEvent event) {
if ("Refreshing resources...".equalsIgnoreCase(event.getJob().getName())) {
refreshJobs++;
}
}
});
}
public IFile generate(IProgressMonitor monitor) throws CoreException {
if (monitor == null) {
monitor = new NullProgressMonitor();
}
monitor.beginTask("Generating Giraph Project", testEnvironment ? 40 : 30);
monitor.subTask("Executing Templates...");
String getLibsXml, giraphCode, utilCode, compileXml, pomXml, launchEnvXml, launchConf, launchXml, installHadoopXml, buildJarLaunch, inputCode;
try {
// Get Java home:
IVMInstall jvm = JavaRuntime.getDefaultVMInstall();
String javaHome = jvm.getInstallLocation().getAbsolutePath();
// Generate rule data:
Map<Rule, GiraphRuleData> ruleData = GiraphUtil.generateRuleData(mainUnit);
// Create template arguments:
Map<String, Object> args = new HashMap<String, Object>();
args.put("javaHome", javaHome);
args.put("ruleData", ruleData);
args.put("mainUnit", mainUnit);
args.put("className", className);
args.put("inputName", inputName);
args.put("packageName", packageName);
args.put("projectName", projectName);
args.put("hostName", getHostName());
args.put("masterLogging", masterLogging);
args.put("vertexLogging", vertexLogging);
args.put("useUUIDs", useUUIDs);
args.put("segmentCount", 1);
args.put("stairCount", 3);
getLibsXml = new GetLibsXmlTemplate().generate(args);
giraphCode = new GiraphRuleTemplate().generate(args);
utilCode = new HenshinUtilTemplate().generate(args);
compileXml = new CompileXmlTemplate().generate(args);
pomXml = new PomXmlTemplate().generate(args);
launchEnvXml = new LaunchEnvXmlTemplate().generate(args);
launchXml = new LaunchXmlTemplate().generate(args);
launchConf = new LaunchConfTemplate().generate(args);
installHadoopXml = new InstallHadoopXmlTemplate().generate(args);
buildJarLaunch = new BuildJarLaunchTemplate().generate(args);
if (inputGraph != null) {
inputCode = GiraphUtil.getInstanceCode(inputGraph);
} else {
inputCode = null;
}
} catch (Exception e) {
throw new CoreException(new Status(IStatus.ERROR, "org.eclipse.emf.henshin.giraph", 0,
"Error executing templates: " + e.getMessage(), e));
}
monitor.worked(1); // 1
monitor.subTask("Initializing Project...");
// Create project:
IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
IProject project = root.getProject(projectName);
if (!project.exists()) {
project.create(null);
}
if (!project.isOpen()) {
project.open(null);
}
project.refreshLocal(IResource.DEPTH_INFINITE, new SubProgressMonitor(monitor, 1));
monitor.worked(1); // 2
// Set Java project nature:
IProjectDescription description = project.getDescription();
description.setNatureIds(new String[] { JavaCore.NATURE_ID });
project.setDescription(description, null);
// Create Java project:
IJavaProject javaProject = JavaCore.create(project);
monitor.worked(1); // 3
// Output folder:
IFolder binFolder = createFolder(project, "bin");
javaProject.setOutputLocation(binFolder.getFullPath(), null);
// Source folders:
IFolder srcFolder = createFolder(project, "src");
IFolder mainFolder = createFolder(srcFolder, "main");
IFolder testFolder = createFolder(srcFolder, "test");
IFolder javaFolder = createFolder(mainFolder, "java");
IFolder javaTestFolder = createFolder(testFolder, "java");
IFolder assemblyFolder = createFolder(mainFolder, "assembly");
IFolder libFolder = createFolder(project, "lib");
IFolder externalToolBuildersFolder = createFolder(project, ".externalToolBuilders");
IFolder inputFolder = createFolder(project, "input");
createFolder(project, "output");
IFolder launchFolder = createFolder(project, "launch");
monitor.worked(1); // 4
// Generate lib/get-libs.xml
IFile getLibsXmlFile = writeFile(libFolder, "get-libs.xml", getLibsXml);
monitor.worked(1); // 5
// Fetch the libraries:
monitor.subTask("Fetching Giraph and Hadoop Libraries...");
AntRunner runner = new AntRunner();
runner.setBuildFileLocation(getLibsXmlFile.getLocation().toOSString());
runner.setArguments("-Dmessage=\"Fetching Giraph and Hadoop Libraries\" -verbose");
runner.run(new SubProgressMonitor(monitor, 5)); // 10
monitor.subTask("Generating Code...");
// Set classpath:
List<IFile> libraries = new ArrayList<IFile>();
List<IFile> sourceAttachments = new ArrayList<IFile>();
for (Entry<URI, URI> lib : GiraphLibraries.LIBRARIES.entrySet()) {
libraries.add(libFolder.getFile(lib.getKey().lastSegment()));
sourceAttachments.add((lib.getValue() != null) ? libFolder.getFile(lib.getValue().lastSegment()) : null);
}
setupClassPath(javaProject, new IFolder[] { javaFolder, javaTestFolder }, libraries.toArray(new IFile[0]),
sourceAttachments.toArray(new IFile[0]));
// Create package:
IPackageFragmentRoot packRoot = javaProject.getPackageFragmentRoot(javaFolder);
IPackageFragment pack = packRoot.createPackageFragment(packageName, false, null);
// Write compute class:
IFile javaUnitFile = writeFile((IFolder) pack.getResource(), className + ".java", giraphCode);
monitor.worked(1); // 11
// Write utility class:
writeFile((IFolder) pack.getResource(), "HenshinUtil.java", utilCode);
monitor.worked(1); // 12
// Example graph:
if (inputCode != null) {
IFile jsonFile = inputFolder.getFile(new Path(inputName + ".json"));
if (!jsonFile.exists()) {
writeFile(jsonFile, inputCode);
}
}
monitor.worked(1); // 13
// Launch files:
writeFile(launchFolder, className + ".xml", launchXml);
writeFile(launchFolder, className + ".launch", launchConf);
monitor.worked(1); // 14
// compile.xml
writeFile(assemblyFolder, "compile.xml", compileXml);
monitor.worked(1); // 15
// pom.xml
writeFile(project, "pom.xml", pomXml);
monitor.worked(1); // 16
// launch-env.xml
writeFile(project, "launch-env.xml", launchEnvXml);
monitor.worked(1); // 17
// build-jar.launch
writeFile(externalToolBuildersFolder, "build-jar.launch", buildJarLaunch);
monitor.worked(1); // 18
// Update external builders:
final int refreshJobsBefore = refreshJobs;
removeExternalToolBuilder(project, "build-jar.launch");
addExternalToolBuilder(project, "build-jar.launch", true);
monitor.worked(1); // 19
if (testEnvironment) {
monitor.subTask("Installing Hadoop Test Environment...");
// testenv/install-hadoop.xml
IFolder testenvFolder = createFolder(project, "testenv");
IFile installHadoop = writeFile(testenvFolder, "install-hadoop.xml", installHadoopXml);
// Fetch Hadoop:
runner = new AntRunner();
runner.setBuildFileLocation(installHadoop.getLocation().toOSString());
runner.setArguments("-Dmessage=\"Installing Hadoop Test Environment\" -verbose");
runner.run(new SubProgressMonitor(monitor, 10)); // 29
}
// Refresh:
project.refreshLocal(IResource.DEPTH_INFINITE, new SubProgressMonitor(monitor, 1)); // 20 / 30
// Wait for Maven refresh jobs (building jar):
final int secs = 900;
IProgressMonitor subMonitor = new SubProgressMonitor(monitor, 10);
monitor.subTask("Building Jar...");
subMonitor.beginTask("Building Jar...", secs);
for (int i = 0; i < secs; i++) {
if (refreshJobs > refreshJobsBefore) {
break;
}
subMonitor.worked(1);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
}
subMonitor.done(); // 30 / 40
monitor.done();
return javaUnitFile;
}
protected void addExternalToolBuilder(IProject project, String name, boolean append) throws CoreException {
IProjectDescription description = project.getDescription();
ICommand[] oldCommands = description.getBuildSpec();
for (ICommand com : oldCommands) {
String val = com.getArguments().get("LaunchConfigHandle");
if (val != null && val.endsWith(name)) {
return;
}
}
ICommand[] newCommands = new ICommand[oldCommands.length + 1];
System.arraycopy(oldCommands, 0, newCommands, append ? 0 : 1, oldCommands.length);
ICommand command = description.newCommand();
command.setBuilderName("org.eclipse.ui.externaltools.ExternalToolBuilder");
Map<String, String> commandArgs = command.getArguments();
commandArgs.put("LaunchConfigHandle", "<project>/.externalToolBuilders/" + name);
command.setArguments(commandArgs);
command.setBuilding(IncrementalProjectBuilder.FULL_BUILD, true);
// command.setBuilding(IncrementalProjectBuilder.INCREMENTAL_BUILD, true);
newCommands[append ? newCommands.length - 1 : 0] = command;
description.setBuildSpec(newCommands);
project.setDescription(description, null);
}
protected IFolder createFolder(IContainer parent, String name) throws CoreException {
IFolder folder = parent.getFolder(new Path(name));
if (!folder.exists()) {
folder.create(false, true, null);
}
return folder;
}
protected void removeExternalToolBuilder(IProject project, String name) throws CoreException {
IProjectDescription description = project.getDescription();
ICommand[] oldCommands = description.getBuildSpec();
List<ICommand> newCommands = new ArrayList<ICommand>();
for (ICommand com : oldCommands) {
String val = com.getArguments().get("LaunchConfigHandle");
if (val == null || !val.endsWith(name)) {
newCommands.add(com);
}
}
description.setBuildSpec(newCommands.toArray(new ICommand[0]));
project.setDescription(description, null);
}
protected void setupClassPath(IJavaProject javaProject, IFolder[] sourceFolders, IFile[] libraries,
IFile[] sourceAttachments) throws CoreException {
List<IClasspathEntry> entries = new ArrayList<IClasspathEntry>();
entries.add(JavaCore
.newContainerEntry(new Path(
"org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7")));
for (IFolder sourceFolder : sourceFolders) {
entries.add(JavaCore.newSourceEntry(javaProject.getPackageFragmentRoot(sourceFolder).getPath()));
}
for (int i = 0; i < libraries.length; i++) {
entries.add(JavaCore.newLibraryEntry(libraries[i].getFullPath(),
sourceAttachments[i] != null ? sourceAttachments[i].getFullPath() : null, null));
}
javaProject.setRawClasspath(entries.toArray(new IClasspathEntry[entries.size()]), true, null);
}
protected IFile writeFile(IContainer container, String fileName, String content) throws CoreException {
IFile file = container.getFile(new Path(fileName));
writeFile(file, content);
return file;
}
protected void writeFile(IFile file, String content) throws CoreException {
if (file.exists()) {
file.setContents(new ByteArrayInputStream(content.getBytes()), IResource.FORCE, null);
} else {
file.create(new ByteArrayInputStream(content.getBytes()), IResource.FORCE, null);
}
}
}