package org.reuseware.air.coconut.ui.eclipse.builder;
import java.io.ByteArrayInputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IncrementalProjectBuilder;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.resources.IResourceVisitor;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.reuseware.air.coconut.IFragmentRetriever;
import org.reuseware.air.coconut.InterpreterSystem;
import org.reuseware.air.util.FileMarker;
import org.reuseware.air.util.FileProcessingException;
import org.reuseware.air.util.FileProcessingProblem;
import org.reuseware.air.util.FragmentFileMap;
import org.reuseware.air.coconut.util.FragmentUtil;
/**
* The builder for Reuseware projects.
*
* @author Jendrik Johannes
*/
public class ReusewareBuilder extends IncrementalProjectBuilder {
public static final String BUILDER_ID = "org.reuseware.coconut.plugin.builder";
protected IProject[] build(int kind, Map args, IProgressMonitor monitor)
throws CoreException {
IProject project = getProject();
ProjectBasedFragmentManager fragmentManager = new ProjectBasedFragmentManager(project);
//InterpreterSystem.getInstance().setFragmentRetriever(new ProjectBasedFragmentManager(project));
fragmentManager.getSourceFolder().accept(new ComponentVisitor());
fragmentManager.getSourceFolder().accept(new CompositionProgramVisitor(fragmentManager));
FragmentFileMap.get().clear();
return null;
}
////////////////////////////ResourceVisitors///////////////////////////////////////
private static class ComponentVisitor implements IResourceVisitor{
public boolean visit(IResource resource) throws CoreException {
if (resource instanceof IFile) {
FileMarker.unmark((IFile)resource);
return false;
}
return true;
}
}
/**
* A file visitor which parses the file, passes the result to
* the CompositionExecutor and prints-back the result to the
* print-back-folder.
*
* @author Jendrik Johannes
*/
private class CompositionProgramVisitor implements IResourceVisitor {
private ProjectBasedFragmentManager manager;
public CompositionProgramVisitor(ProjectBasedFragmentManager manager){
this.manager = manager;
}
public boolean visit(IResource resource) throws CoreException {
if (!(resource instanceof IFile)) {
return true;
}
IFile file = (IFile) resource;
if (file.getFileExtension() == null)
return true;
IProject project = resource.getProject();
IFile outFile = null;
String extension = file.getFileExtension();
// TODO: motivate this check
if (extension.startsWith("r") || extension.startsWith("m") ||
extension.startsWith("reuse") || extension.startsWith("e")) {
if (extension.startsWith("reuse"))
extension = extension.substring(5);
else if (extension.startsWith("r"))
extension = extension.substring(1);
else if (extension.startsWith("m"))
extension = extension.substring(1);
outFile =
manager.getPrintFolder().getFile(file.getFullPath().removeFirstSegments(2).removeFileExtension().addFileExtension(extension));
}
try {
IFragmentRetriever fr = manager;
FileMarker.unmark(file);
List<EObject> programs =
fr.getFragmentFromLocation(file.getFullPath().toString(), file.getContents(), null, null);
List<FileProcessingProblem> problems = new ArrayList<FileProcessingProblem>();
// go through fragments in the composition program
for(EObject program : programs) {
Map<String,List<EObject>> env = new HashMap<String,List<EObject>>();
Map<String,EClass> envTypes = new HashMap<String, EClass>();
InterpreterSystem.getInstance().interpret(program, env, envTypes, problems);
}
if (!problems.isEmpty())
throw new FileProcessingException(problems);
if (outFile != null) {
// check for unbound slots
for (EObject fragment : programs) {
String name =
FragmentUtil.containsSlot(fragment);
if (name != null) {
problems.add(new FileProcessingProblem(fragment,
"File " + file.toString() + " contains unbound slot '" + name + "'"));
throw new FileProcessingException(problems);
}
}
StringBuffer output =
(StringBuffer) fr.printFragments(outFile.getFullPath().removeFirstSegments(2).toString(), programs, null);
if (outFile.exists())
outFile.delete(true, new NullProgressMonitor());
outFile.create(new ByteArrayInputStream(output.toString().getBytes()), true, new NullProgressMonitor());
}
} catch (FileProcessingException e) {
FileMarker.mark(e, project);
}
return true;
}
}
}