package com.gorillalogic.monkeyconsole.builder;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
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.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.xml.sax.helpers.DefaultHandler;
import com.gorillalogic.monkeytalk.api.js.tools.JSLibGenerator;
public class MonkeyTalkBuilder extends IncrementalProjectBuilder {
class MonkeyTalkDeltaVisitor implements IResourceDeltaVisitor {
/*
* (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();
switch (delta.getKind()) {
case IResourceDelta.ADDED:
// handle added resource
checkMonkeyTalk(resource);
break;
case IResourceDelta.REMOVED:
checkMonkeyTalk(resource);
break;
case IResourceDelta.CHANGED:
checkMonkeyTalk(resource);
break;
}
// return true to continue visiting children.
return true;
}
}
class MonkeyTalkResourceVisitor implements IResourceVisitor {
public boolean visit(IResource resource) {
checkMonkeyTalk(resource);
// return true to continue visiting children.
return true;
}
}
// This is just a class stub to be fixed later
class MonkeyTalkException extends Exception {
public int getLineNumber() {
return 0;
}
}
class MonkeyTalkParser {
}
class MonkeyTalkErrorHandler extends DefaultHandler {
private IFile file;
public MonkeyTalkErrorHandler(IFile file) {
this.file = file;
}
private void addMarker(MonkeyTalkException e, int severity) {
MonkeyTalkBuilder.this.addMarker(file, e.getMessage(), e.getLineNumber(), severity);
}
public void error(MonkeyTalkException exception) {
addMarker(exception, IMarker.SEVERITY_ERROR);
}
public void fatalError(MonkeyTalkException exception) {
addMarker(exception, IMarker.SEVERITY_ERROR);
}
public void warning(MonkeyTalkException exception) {
addMarker(exception, IMarker.SEVERITY_WARNING);
}
}
public static final String BUILDER_ID = "com.gorillalogic.monkeyconsole.builder.monkeyTalkBuilder";
private static final String MARKER_TYPE = "com.gorillalogic.monkeyconsole.builder.monkeyTalkProblem";
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) {
}
}
/*
* (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;
}
void checkMonkeyTalk(IResource resource) {
if (resource instanceof IFile && resource.getName().endsWith(".mt")) {
IFile file = (IFile) resource;
deleteMarkers(file);
reginLib(file);
MonkeyTalkErrorHandler reporter = new MonkeyTalkErrorHandler(file);
// try {
// getParser().parse(file.getContents(), reporter);
// } catch (Exception e1) {
// }
}
if (resource instanceof IFile && resource.getName().endsWith(".mts")) {
IFile file = (IFile) resource;
deleteMarkers(file);
MonkeyTalkErrorHandler reporter = new MonkeyTalkErrorHandler(file);
reginLib(file);
// try {
// getParser().parse(file.getContents(), reporter);
// } catch (Exception e1) {
// }
}
}
private void reginLib(IFile file) {
// compute the parent folder, and the libs folder
File dir = new File(file.getRawLocationURI().getRawPath().toString()).getParentFile();
File libs = new File(dir, "libs");
// first, we regen the lib
try {
String jsLIB = JSLibGenerator.createLib(file.getProject().getName(), dir);
FileUtils.writeStringToFile(new File(libs, file.getProject().getName() + ".js"), jsLIB);
} catch (IOException ex) {
ex.printStackTrace();
}
// second, we re-copy the API (just in case they upgraded)
try {
InputStream is = Thread.currentThread().getContextClassLoader()
.getResourceAsStream("templates/MonkeyTalkAPI.js");
IOUtils.copy(is, new FileOutputStream(new File(libs, "/MonkeyTalkAPI.js")));
} catch (IOException ex) {
ex.printStackTrace();
}
// last, we refresh the workspace to pick everything up
try {
file.getProject().refreshLocal(IResource.DEPTH_INFINITE, null);
} catch (CoreException e) {
// Could not refresh workspace, no biggie
}
}
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 {
getProject().accept(new MonkeyTalkResourceVisitor());
} catch (CoreException e) {
}
}
private MonkeyTalkParser getParser() {
// TODO
return null;
}
protected void incrementalBuild(IResourceDelta delta, IProgressMonitor monitor)
throws CoreException {
// the visitor does the work.
delta.accept(new MonkeyTalkDeltaVisitor());
}
}