/*
* #%~
* org.overture.ide.core
* %%
* Copyright (C) 2008 - 2014 Overture
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program. If not, see
* <http://www.gnu.org/licenses/gpl-3.0.html>.
* #~%
*/
package org.overture.ide.core.builder;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.ISafeRunnable;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.SafeRunner;
import org.overture.ide.core.ICoreConstants;
import org.overture.ide.core.IVdmModel;
import org.overture.ide.core.VdmCore;
import org.overture.ide.core.ast.VdmModelWorkingCopy;
import org.overture.ide.core.parser.SourceParserManager;
import org.overture.ide.core.resources.IVdmProject;
public class SafeBuilder extends Thread
{
final IVdmProject currentProject;
final IProgressMonitor monitor;
public SafeBuilder(final IVdmProject currentProject,
final IProgressMonitor monitor)
{
this.currentProject = currentProject;
this.monitor = monitor;
this.setName("VDM Safe Builder");
this.setDaemon(true);
}
@Override
public void run()
{
try
{
IConfigurationElement[] config = Platform.getExtensionRegistry().getConfigurationElementsFor(ICoreConstants.EXTENSION_BUILDER_ID);
for (IConfigurationElement e : config)
{
if (currentProject.getVdmNature().equals(e.getAttribute("nature")))
{
final Object o = e.createExecutableExtension("class");
if (o instanceof AbstractVdmBuilder)
{
ISafeRunnable runnable = new ISafeRunnable()
{
public void handleException(Throwable e)
{
VdmCore.log("SafeBuilder", e);
}
public void run() throws Exception
{
AbstractVdmBuilder builder = (AbstractVdmBuilder) o;
final IVdmModel model = currentProject.getModel();
if (model != null)
{
clearProblemMarkers((IProject) currentProject.getAdapter(IProject.class));
//first fix source model
SourceParserManager.parseMissingFiles(currentProject, model, monitor);
//create working copy from source model to be checked
VdmModelWorkingCopy workingModel = model.getWorkingCopy();
// if the project is parsed with no errors
if (model.isParseCorrect())
{
try
{
if (VdmCore.DEBUG)
{
System.out.println("Type Checking: "
+ currentProject.getName());
}
monitor.subTask("Type checking: "
+ currentProject);
IStatus status = builder.buildModel(currentProject, workingModel);
// mark ast root as type checked
if (workingModel != null)
{
workingModel.setTypeCheckedStatus(status.isOK());
//override any existing model and source units
workingModel.commit();
}
if(!status.isOK())
{
if(status.getException()!=null)
{
handleException(status.getException());
}
}
} catch (Exception e)
{
workingModel.discard();
throw e;
} finally
{
monitor.done();
}
return;
} else
{
workingModel.discard();
}
}
}
};
SafeRunner.run(runnable);
break;
}
}
}
} catch (Exception ex)
{
System.out.println(ex.getMessage());
VdmCore.log(ex);
}
}
/***
* This method removed all problem markers and its sub-types from the project. It is called before an instance of
* the AbstractBuilder is created
*
* @param project
* The project which should be build.
*/
public static void clearProblemMarkers(IProject project)
{
try
{
project.deleteMarkers(IMarker.PROBLEM, true, IResource.DEPTH_INFINITE);
} catch (CoreException e)
{
VdmCore.log("VdmCoreBuilder:clearProblemMarkers", e);
}
}
}