blob: 905c867b34ea9a156691dd7a78478fcf7106bb35 [file] [log] [blame]
/**
* <copyright>
*
* Copyright (c) 2007-2009 Metascape, LLC
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Metascape - Development and maintenance
*
* </copyright> $Id: AbstractMWEBuilder.java,v 1.4 2010/08/04 01:54:01 mparker Exp $
*/
package org.eclipse.amp.amf.gen.ide;
import java.net.URL;
import java.util.HashMap;
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.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.mwe.core.WorkflowEngine;
import org.eclipse.emf.mwe.core.WorkflowRunner;
import org.eclipse.emf.mwe.core.issues.Issues;
import org.eclipse.emf.mwe.core.monitor.NullProgressMonitor;
import org.eclipse.emf.mwe.core.monitor.ProgressMonitor;
import org.eclipse.emf.mwe.core.monitor.ProgressMonitorAdapter;
import org.eclipse.emf.mwe.core.resources.ResourceLoader;
import org.eclipse.ui.statushandlers.StatusManager;
/**
* Provides basic services for invoking a workflow against all .metaabm models within a project. particular support for
* workflow logging, markers
*
* @author milesparker
*
*/
public abstract class AbstractMWEBuilder extends IncrementalProjectBuilder {
String sourceExtension;
protected String[] workflowPaths;
ExtendedResourceLoader resourceLoader;
protected static MetaABMBuilder builder;
private Map<String, String> genProps;
protected IProgressMonitor currentMonitor;
boolean createMarkers;
private ModelMarkerHelper modelMarkerHelper;
WorkflowUIExceptionHandler exceptionHandler;
private String taskDescription;
private String pluginName;
private boolean reportErrors = true;
public AbstractMWEBuilder(String taskDescription, String pluginName, String workflowPath, String sourceExtension) {
this(taskDescription, pluginName, new String[] { workflowPath }, sourceExtension);
}
public AbstractMWEBuilder(String taskDescription, String pluginName, String[] workflowPaths, String sourceExtension) {
this.taskDescription = taskDescription;
this.pluginName = pluginName;
this.workflowPaths = workflowPaths;
this.sourceExtension = sourceExtension;
setGenProperties(new HashMap<String, String>());
loadPlugins();
}
public void addURL(URL url) throws CoreException {
resourceLoader.addURL(url);
}
private class GenerationRunner extends WorkflowEngine {
@Override
public boolean executeWorkflow(Map<?, ?> externalSlotContents, Issues issues) {
boolean result = false;
result = super.executeWorkflow(externalSlotContents, issues);
if (createMarkers) {
modelMarkerHelper.addMarkers(issues);
}
return result;
}
}
class BuilderDeltaVisitor 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
handleModifiedResource(resource);
break;
case IResourceDelta.REMOVED:
// For now, we won't try to delete existing java files
// handle removed resource
break;
case IResourceDelta.CHANGED:
// handle changed resource
handleModifiedResource(resource);
break;
}
// return true to continue visiting children.
return true;
}
}
class BuilderResourceVisitor implements IResourceVisitor {
public boolean visit(IResource resource) {
handleModifiedResource(resource);
return true;
}
}
public abstract void loadPlugins();
public ResourceLoader getResourceLoader() {
return resourceLoader;
}
public void generateModel(IResource resource) {
ClassLoader oldLoader = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
LogWorkflow.registerToLogFactory();
String projectName = resource.getProject().getName();
String fileName = resource.getName();
String fullTaskDescription = taskDescription + " for " + fileName + " in " + projectName;
// String location = "Workflow: " + workflowPath + " Model: " + fileName;
if (createMarkers) {
modelMarkerHelper = new ModelMarkerHelper(resource);
modelMarkerHelper.deleteMarkers();
}
WorkflowEngine workflowRunner = new GenerationRunner();
ProgressMonitor workflowMonitor;
if (currentMonitor != null) {
workflowMonitor = new ProgressMonitorAdapter(currentMonitor);
} else {
workflowMonitor = new NullProgressMonitor();
workflowMonitor.setTaskName(fullTaskDescription);
}
exceptionHandler = new WorkflowUIExceptionHandler();
Map<String, Object> slotContents = new HashMap<String, Object>();
slotContents.put("progressMonitor", currentMonitor);
slotContents.put("exceptionHandler", exceptionHandler);
loadPropertiesFromPrefs();
boolean success = true;
for (String workflow : workflowPaths) {
success &= workflowRunner.run(workflow, workflowMonitor, getGenProperties(), slotContents);
if (!success) {
break;
}
}
LogWorkflow.setSuccess(success);
LogWorkflow.report(pluginName, fullTaskDescription, false);
LogWorkflow.restoreLogFactory();
Thread.currentThread().setContextClassLoader(oldLoader);
}
protected void loadPropertiesFromPrefs() {
}
public void loadPropertiesFromResource(IResource resource) {
getGenProperties().put("modelFile", resource.getName());
URI resourceURI = URI.createPlatformResourceURI(resource.getProject().getName() + "/"
+ resource.getProjectRelativePath(), true);
getGenProperties().put("modelPath", resourceURI.toPlatformString(true));
getGenProperties().put("outputPath", resource.getProject().getLocation().addTrailingSeparator().toOSString());
getGenProperties().put("buildProject", resource.getProject().getName());
}
public void handleModifiedResource(IResource resource) {
if (resource instanceof IFile && resource.getName().endsWith(sourceExtension)) {
loadPropertiesFromResource(resource);
generateModel(resource);
try {
resource.getProject().refreshLocal(IResource.DEPTH_INFINITE, null);
} catch (CoreException e) {
StatusManager.getManager().handle(
new Status(IStatus.ERROR, "org.eclipse.amp.amf.gen",
"Couldn't refresh model.", e), StatusManager.SHOW);
throw new RuntimeException("Core issue when generating model", e);
}
}
}
protected IProject[] build(int kind, Map args, IProgressMonitor monitor) throws CoreException {
currentMonitor = monitor;
if (kind == FULL_BUILD) {
fullBuild(monitor);
} else {
IResourceDelta delta = getDelta(getProject());
if (delta == null) {
fullBuild(monitor);
} else {
incrementalBuild(delta, monitor);
}
}
currentMonitor = null;
return null;
}
protected void fullBuild(final IProgressMonitor monitor) throws CoreException {
getProject().accept(new BuilderResourceVisitor());
}
protected void incrementalBuild(IResourceDelta delta, IProgressMonitor monitor) throws CoreException {
// the visitor does the work.
delta.accept(new BuilderDeltaVisitor());
}
public void setGenProperties(Map<String, String> genProps) {
this.genProps = genProps;
}
public Map<String, String> getGenProperties() {
return genProps;
}
public void setCurrentMonitor(IProgressMonitor currentMonitor) {
this.currentMonitor = currentMonitor;
}
public boolean isReportErrors() {
return reportErrors;
}
public void setReportErrors(boolean reportErrors) {
this.reportErrors = reportErrors;
}
}