Skip to content

Instantly share code, notes, and snippets.

@ribrdb
Created April 5, 2011 14:56
Show Gist options
  • Select an option

  • Save ribrdb/903762 to your computer and use it in GitHub Desktop.

Select an option

Save ribrdb/903762 to your computer and use it in GitHub Desktop.
package org.mirah.core.builder;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.core.resources.IResourceDeltaVisitor;
import org.eclipse.core.resources.IResourceVisitor;
import org.eclipse.core.resources.IncrementalProjectBuilder;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.mirah.MirahCommand;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.helpers.DefaultHandler;
public class MirahBuilder extends IncrementalProjectBuilder {
class SampleDeltaVisitor implements IResourceDeltaVisitor {
private Set<IResource> resources;
public SampleDeltaVisitor(Set<IResource> resources) {
this.resources = resources;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.core.resources.IResourceDeltaVisitor#visit(org.eclipse.core.resources.IResourceDelta)
*/
public boolean visit(IResourceDelta delta) throws CoreException {
IResource resource = delta.getResource();
if (resource instanceof IFile && resource.getName().endsWith(".mirah")) {
switch (delta.getKind()) {
case IResourceDelta.ADDED:
// handle added resource
resources.add(resource);
break;
case IResourceDelta.REMOVED:
// handle removed resource
break;
case IResourceDelta.CHANGED:
// handle changed resource
resources.add(resource);
break;
}
}
//return true to continue visiting children.
return true;
}
}
class SampleResourceVisitor implements IResourceVisitor {
private Set<IResource> resources;
public SampleResourceVisitor(Set<IResource> resources) {
this.resources = resources;
}
public boolean visit(IResource resource) {
resources.add(resource);
//return true to continue visiting children.
return true;
}
}
class ClasspathBuilder {
private StringBuffer classpath = new StringBuffer();
private Set<String> visitedFiles = new HashSet<String>();
private Set<IJavaProject> visitedProjects = new HashSet<IJavaProject>();
private IJavaProject project;
public ClasspathBuilder(IJavaProject project) {
this.project = project;
}
public String buildClasspath() {
if (visitedProjects.size() == 0) {
visitProject(project);
}
return classpath.toString();
}
private void visitProject(IJavaProject project) {
boolean first = visitedProjects.size() == 0;
if (visitedProjects.contains(project)) {
return;
}
visitedProjects.add(project);
try {
visitPath(project.getOutputLocation());
for (IClasspathEntry entry : project.getResolvedClasspath(true)) {
switch (entry.getEntryKind()) {
case IClasspathEntry.CPE_LIBRARY:
visitPath(entry.getPath());
break;
case IClasspathEntry.CPE_PROJECT:
if (first || entry.isExported()) {
visitProject(getJavaProject(entry));
}
break;
case IClasspathEntry.CPE_SOURCE:
visitPath(entry.getOutputLocation());
}
}
} catch (JavaModelException e) {
e.printStackTrace();
return;
}
}
private IJavaProject getJavaProject(IClasspathEntry entry) {
IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(entry.getPath().segment(0));
if (project == null) {
return null;
} else {
return JavaCore.create(project);
}
}
private void visitPath(IPath path) {
if (path == null) {
return;
}
String filename = getLocation(path);
if (filename == null) {
return;
}
if (visitedFiles.contains(filename)) {
return;
}
visitedFiles.add(filename);
if (classpath.length() > 0) {
classpath.append(File.pathSeparator);
}
classpath.append(filename);
}
}
public static final String BUILDER_ID = "org.mirah.core.mirahBuilder";
private static final String MARKER_TYPE = "org.mirah.core.mirahProblem";
private void addMarker(IFile file, String message, int lineNumber,
int severity) {
try {
IMarker marker = file.createMarker(MARKER_TYPE);
marker.setAttribute(IMarker.MESSAGE, message);
marker.setAttribute(IMarker.SEVERITY, severity);
if (lineNumber == -1) {
lineNumber = 1;
}
marker.setAttribute(IMarker.LINE_NUMBER, lineNumber);
} catch (CoreException e) {
}
}
public void compileResources(Set<IResource> resources) throws JavaModelException {
ArrayList<String> args = new ArrayList<String>();
IJavaProject project = JavaCore.create(getProject());
String classpath = new ClasspathBuilder(project).buildClasspath();
args.add("--classpath");
args.add(classpath);
args.add("-d");
args.add(getLocation(project.getOutputLocation()));
int files = 0;
IFile file = null;
for (IResource resource : resources) {
if (resource instanceof IFile && resource.getName().endsWith(".mirah")) {
file = (IFile) resource;
deleteMarkers(file);
args.add(file.getLocation().toOSString());
files += 1;
}
}
if (files > 0) {
try {
MirahCommand.compile(args);
} catch (Exception ex) {
addMarker(file, ex.getLocalizedMessage(), -1, IMarker.SEVERITY_ERROR);
}
}
}
/*
* (non-Javadoc)
*
* @see org.eclipse.core.internal.events.InternalBuilder#build(int,
* java.util.Map, org.eclipse.core.runtime.IProgressMonitor)
*/
protected IProject[] build(int kind, Map args, IProgressMonitor monitor)
throws CoreException {
if (kind == FULL_BUILD) {
fullBuild(monitor);
} else {
IResourceDelta delta = getDelta(getProject());
if (delta == null) {
fullBuild(monitor);
} else {
incrementalBuild(delta, monitor);
}
}
return null;
}
private void deleteMarkers(IFile file) {
try {
file.deleteMarkers(MARKER_TYPE, false, IResource.DEPTH_ZERO);
} catch (CoreException ce) {
}
}
protected void fullBuild(final IProgressMonitor monitor)
throws CoreException {
try {
Set<IResource> resources = new HashSet<IResource>();
getProject().accept(new SampleResourceVisitor(resources));
compileResources(resources);
} catch (CoreException e) {
}
}
protected void incrementalBuild(IResourceDelta delta,
IProgressMonitor monitor) throws CoreException {
Set<IResource> resources = new HashSet<IResource>();
delta.accept(new SampleDeltaVisitor(resources));
compileResources(resources);
}
private String getLocation(IPath path) {
if (path.toFile().canRead()) {
return path.toOSString();
}
IResource resource = ResourcesPlugin.getWorkspace().getRoot().findMember(path);
if (resource == null) {
System.err.println("Can't find resource " + path);
return null;
}
return resource.getLocation().toOSString();
}
}
package org.mirah.core.builder;
import org.eclipse.core.resources.ICommand;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectDescription;
import org.eclipse.core.resources.IProjectNature;
import org.eclipse.core.runtime.CoreException;
public class MirahNature implements IProjectNature {
/**
* ID of this project nature
*/
public static final String NATURE_ID = "org.mirah.core.mirahNature";
private IProject project;
/*
* (non-Javadoc)
*
* @see org.eclipse.core.resources.IProjectNature#configure()
*/
public void configure() throws CoreException {
IProjectDescription desc = project.getDescription();
ICommand[] commands = desc.getBuildSpec();
for (int i = 0; i < commands.length; ++i) {
if (commands[i].getBuilderName().equals(MirahBuilder.BUILDER_ID)) {
return;
}
}
ICommand[] newCommands = new ICommand[commands.length + 1];
System.arraycopy(commands, 0, newCommands, 0, commands.length);
ICommand command = desc.newCommand();
command.setBuilderName(MirahBuilder.BUILDER_ID);
newCommands[newCommands.length - 1] = command;
desc.setBuildSpec(newCommands);
project.setDescription(desc, null);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.core.resources.IProjectNature#deconfigure()
*/
public void deconfigure() throws CoreException {
IProjectDescription description = getProject().getDescription();
ICommand[] commands = description.getBuildSpec();
for (int i = 0; i < commands.length; ++i) {
if (commands[i].getBuilderName().equals(MirahBuilder.BUILDER_ID)) {
ICommand[] newCommands = new ICommand[commands.length - 1];
System.arraycopy(commands, 0, newCommands, 0, i);
System.arraycopy(commands, i + 1, newCommands, i,
commands.length - i - 1);
description.setBuildSpec(newCommands);
project.setDescription(description, null);
return;
}
}
}
/*
* (non-Javadoc)
*
* @see org.eclipse.core.resources.IProjectNature#getProject()
*/
public IProject getProject() {
return project;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.core.resources.IProjectNature#setProject(org.eclipse.core.resources.IProject)
*/
public void setProject(IProject project) {
this.project = project;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment