/**
* <copyright>
* </copyright>
*
*
*/
package org.dresdenocl.language.ocl.resource.ocl.mopp;
import java.util.LinkedHashMap;
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.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.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
public class OclBuilderAdapter extends IncrementalProjectBuilder {
private static class ResourceCollector implements IResourceDeltaVisitor, IResourceVisitor {
private Map<IResource, Boolean> resourceMap = new LinkedHashMap<IResource, Boolean>();
public boolean visit(IResourceDelta delta) throws CoreException {
IResource resource = delta.getResource();
return doVisit(resource, delta.getKind() == IResourceDelta.REMOVED);
}
public boolean visit(IResource resource) throws CoreException {
return doVisit(resource, false);
}
private boolean doVisit(IResource resource, boolean removed) throws CoreException {
resourceMap.put(resource, removed);
return true;
}
private Map<IResource, Boolean> getResourceMap() {
return resourceMap;
}
}
/**
* The ID of the default, generated builder.
*/
public final static String BUILDER_ID = "org.dresdenocl.language.ocl.resource.ocl.builder";
private org.dresdenocl.language.ocl.resource.ocl.IOclBuilder defaultBuilder = new org.dresdenocl.language.ocl.resource.ocl.mopp.OclBuilder();
public IProject[] build(int kind, Map<String, String> args, final IProgressMonitor monitor) throws CoreException {
// Collect resources that must be built
ResourceCollector resourceCollector = new ResourceCollector();
IResourceDelta delta = getDelta(getProject());
if (delta != null) {
// This is an incremental build
delta.accept(resourceCollector);
} else {
// This is a full build
getProject().accept(resourceCollector);
}
// This resource set is used during the whole build.
ResourceSet resourceSet = new ResourceSetImpl();
Map<IResource, Boolean> resourceMap = resourceCollector.getResourceMap();
monitor.beginTask(org.dresdenocl.language.ocl.resource.ocl.OclResourceBundle.BUILDER_ADAPTER_TASK_NAME, resourceMap.size() * 2);
for (IResource resource : resourceMap.keySet()) {
doVisit(resource, resourceMap.get(resource), monitor, resourceSet);
}
monitor.done();
return null;
}
public void build(IFile resource, ResourceSet resourceSet, IProgressMonitor monitor) {
URI uri = URI.createPlatformResourceURI(resource.getFullPath().toString(), true);
org.dresdenocl.language.ocl.resource.ocl.IOclBuilder builder = getBuilder();
if (builder.isBuildingNeeded(uri)) {
org.dresdenocl.language.ocl.resource.ocl.mopp.OclResource customResource = (org.dresdenocl.language.ocl.resource.ocl.mopp.OclResource) resourceSet.getResource(uri, true);
new org.dresdenocl.language.ocl.resource.ocl.mopp.OclMarkerHelper().removeAllMarkers(resource, getBuilderMarkerId());
builder.build(customResource, monitor);
}
}
/**
* Returns the builder that shall be used by this adapter. This allows subclasses
* to perform builds with different builders.
*/
public org.dresdenocl.language.ocl.resource.ocl.IOclBuilder getBuilder() {
return defaultBuilder;
}
/**
* Returns the id for the markers that are created by this builder. This allows
* subclasses to produce different kinds of markers.
*/
public String getBuilderMarkerId() {
return new org.dresdenocl.language.ocl.resource.ocl.mopp.OclMarkerHelper().getMarkerID(org.dresdenocl.language.ocl.resource.ocl.OclEProblemType.BUILDER_ERROR);
}
/**
* Runs the task item builder to search for new task items in changed resources.
*/
public void runTaskItemBuilder(IFile resource, ResourceSet resourceSet, IProgressMonitor monitor) {
org.dresdenocl.language.ocl.resource.ocl.mopp.OclTaskItemBuilder taskItemBuilder = new org.dresdenocl.language.ocl.resource.ocl.mopp.OclTaskItemBuilder();
taskItemBuilder.build(resource, resourceSet, monitor);
}
protected boolean doVisit(IResource resource, boolean removed, IProgressMonitor monitor, ResourceSet resourceSet) throws CoreException {
if (removed) {
URI uri = URI.createPlatformResourceURI(resource.getFullPath().toString(), true);
org.dresdenocl.language.ocl.resource.ocl.IOclBuilder builder = getBuilder();
if (builder.isBuildingNeeded(uri)) {
builder.handleDeletion(uri, monitor);
}
new org.dresdenocl.language.ocl.resource.ocl.mopp.OclMarkerHelper().removeAllMarkers(resource, getBuilderMarkerId());
return false;
}
if (resource instanceof IFile && resource.getName().endsWith("." + new org.dresdenocl.language.ocl.resource.ocl.mopp.OclMetaInformation().getSyntaxName())) {
// First, call the default generated builder that is usually customized to add
// compilation-like behavior. The Builder may consume one tick from the progress
// monitor.
build((IFile) resource, resourceSet, monitor);
// Second, call the task item builder that searches for task items in DSL
// documents and creates task markers. The TaskItemBuilder may consume one tick
// from the progress monitor.
runTaskItemBuilder((IFile) resource, resourceSet, monitor);
return false;
}
return true;
}
}