package tool.builder;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
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.IncrementalProjectBuilder;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.QualifiedName;
import tool.ToolPlugin;
import tool.ToolProjectSupport;
import tool.repository.CommandException;
import tool.repository.NotConnectedException;
import tool.repository.RepositorySession;
import tool.repository.FScript;
public class ToolBuilder extends IncrementalProjectBuilder {
public static final String BUILDER_ID = "Tool.ToolBuilder";
public static final String COMPILE_ERROR_REGEX = "(project|method):([a-zA-Z_.]+):error:Line (\\d+):(.+)";
public static final Pattern pattern = Pattern.compile(COMPILE_ERROR_REGEX);
private static final String MARKER_TYPE = "tool.marker.problemMarker";
protected IProject[] build(int kind, Map args,
IProgressMonitor monitor) {
if (kind == IncrementalProjectBuilder.FULL_BUILD) {
fullBuild(monitor);
} else {
IResourceDelta delta = getDelta(getProject());
if (delta == null) {
fullBuild(monitor);
} else {
incrementalBuild(delta, monitor);
}
}
getRepository(getProject()).setJustRefreshed(false);
return null;
}
private void incrementalBuild(IResourceDelta delta,
IProgressMonitor monitor) {
final IProgressMonitor mon = monitor;
System.out.println("incremental build on " + delta);
try {
delta.accept(new IResourceDeltaVisitor() {
public boolean visit(IResourceDelta delta) {
if (mon.isCanceled())
return false;
if (delta.getKind() == IResourceDelta.REMOVED){
System.out.println("removed: "+
delta.getResource().getRawLocation());
return false;
}
String osName = System.getProperty("os.name");
if (!osName.startsWith("Windows")){ // Only run it on windows
ToolPlugin.log(IStatus.INFO, "-- Can only build on Windows --");
return false;
}
if (delta.getKind() == IResourceDelta.CHANGED && delta.getResource() instanceof IFile){
IFile file = (IFile)delta.getResource();
if (file.getFileExtension().equalsIgnoreCase("cex") ||
file.getFileExtension().equalsIgnoreCase("cdf")){
try {
file.deleteMarkers(MARKER_TYPE, true, IResource.DEPTH_ONE);
} catch (CoreException e) {
ToolPlugin.showError("Error deleting file markers", e);
}
IProject project = file.getProject();
RepositorySession session = RepositorySession.getRepositorySession(project);
if (session != null){
if (session.isJustRefreshed())
return false;
IFolder plan = (IFolder) file.getParent();
String result;
try {
if (!session.isRepositoryOpen()){
session.openRepository();
}
if (!session.isWorkspaceOpen()){
session.openWorkspace();
}
mon.subTask("Compiling: " + file.getName());
result = session.compileComponent(plan.getName(), file.getLocation().toPortableString());
if (result != null)
processCompileErrors(file, result);
} catch (NotConnectedException e) {
ToolPlugin.showError("Tool System Exception", e);
} catch (CommandException e) {
ToolPlugin.showError("Tool System Exception", e);
} finally {
mon.worked(1);
}
}
} else if (file.getFileExtension().equalsIgnoreCase("fsw")){
System.out.println("Building Tool Window: " + file);
}
return false; //no kids to visit
}
return true; // visit children too
}
});
} catch (CoreException e) {
ToolPlugin.showError("Error in Incremental build.", e);
}
}
protected void processCompileErrors(IFile file, String result){
if (result.contains("ERROR: Errors in compile")){
Matcher errors = pattern.matcher(result);
while (errors.find()){
String wholeMatch = errors.group(0);
String scope = errors.group(1);
String fullMethodName = errors.group(2);
int fileLine = Integer.parseInt(errors.group(3));
String errrorMessage = errors.group(4);
addMarker(file, errrorMessage, fileLine, IMarker.SEVERITY_ERROR);
}
}
}
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) {
}
}
private void fullBuild(IProgressMonitor monitor) {
System.out.println("full build");
}
/**
* locate a connection to a Tool Repository by obtaining a
* previously located Repository from a session property on the Project
* OR
* create a new one and add it to the session property
*
* @param project
* @return
*/
public static FScript getRepository(IProject project){
FScript repos = null;
try {
repos = (FScript)project.getSessionProperty(new QualifiedName(ToolProjectSupport.PROJECT_QUALIFIED_NAME, ToolProjectSupport.REPOS_OBJECT));
if (repos == null){
/*
* create a ToolRepository based on the project properties
* and store it as a session property
*/
String forteRoot = project.getPersistentProperty(ToolProjectSupport.forteRootQualifiedName);
String repository = project.getPersistentProperty(ToolProjectSupport.reposQualifiedName);
String workspace = project.getPersistentProperty(ToolProjectSupport.workspaceQualifiedName);
String workspacePassword = project.getPersistentProperty(ToolProjectSupport.worspacePasswordQualifiedName);
String logFlags = project.getPersistentProperty(ToolProjectSupport.loggerQualifiedName);
repos = new FScript(forteRoot, repository, workspace, workspacePassword, logFlags, true);
project.setSessionProperty(new QualifiedName(ToolProjectSupport.PROJECT_QUALIFIED_NAME, ToolProjectSupport.REPOS_OBJECT), repos);
}
} catch (CoreException e) {
ToolPlugin.showError("Error getting repository", e);
}
return repos;
}
}