Created
April 5, 2011 14:56
-
-
Save ribrdb/903761 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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(); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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