/*******************************************************************************
* Copyright (c) 2014 Bruno Medeiros and other Contributors.
* 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:
* Bruno Medeiros - initial API and implementation
*******************************************************************************/
package melnorme.lang.ide.core.operations;
import static melnorme.utilbox.core.Assert.AssertNamespace.assertTrue;
import java.util.Map;
import org.eclipse.core.resources.IBuildConfiguration;
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 melnorme.lang.ide.core.EclipseCore;
import melnorme.lang.ide.core.LangCore;
import melnorme.lang.ide.core.LangCore_Actual;
import melnorme.lang.ide.core.operations.build.BuildManager;
import melnorme.lang.ide.core.utils.EclipseUtils;
import melnorme.lang.ide.core.utils.ResourceUtils;
import melnorme.lang.ide.core.utils.operation.EclipseJobOperation;
import melnorme.utilbox.collections.ArrayList2;
import melnorme.utilbox.concurrency.OperationCancellation;
import melnorme.utilbox.core.CommonException;
import melnorme.utilbox.misc.Location;
public abstract class LangProjectBuilder extends IncrementalProjectBuilder {
protected final BuildManager buildManager = LangCore.getBuildManager();
public LangProjectBuilder() {
}
protected Location getProjectLocation() throws CommonException {
return ResourceUtils.getProjectLocation2(getProject());
}
protected ToolManager getToolManager() {
return LangCore.getToolManager();
}
/* ----------------- helpers ----------------- */
protected String getBuildProblemId() {
return LangCore_Actual.BUILD_PROBLEM_ID;
}
protected boolean isFirstProjectOfKind() throws CoreException {
for (IBuildConfiguration buildConfig : getContext().getAllReferencedBuildConfigs()) {
if(buildConfig.getProject().hasNature(LangCore.NATURE_ID)) {
return false;
}
}
return true;
}
protected boolean isLastProjectOfKind() throws CoreException {
for (IBuildConfiguration buildConfig : getContext().getAllReferencingBuildConfigs()) {
if(buildConfig.getProject().hasNature(LangCore.NATURE_ID)) {
return false;
}
}
return true;
}
/* ----------------- Build ----------------- */
@Override
protected void startupOnInitialize() {
assertTrue(getProject() != null);
}
@Override
protected IProject[] build(int kind, Map<String, String> args, IProgressMonitor monitor) throws CoreException {
assertTrue(kind != CLEAN_BUILD);
if(kind == IncrementalProjectBuilder.AUTO_BUILD) {
return null; // Ignore auto build
}
ArrayList2<IProject> referenced =
ArrayList2.createFrom(getContext().getAllReferencedBuildConfigs())
.map((buildConfig) -> buildConfig.getProject())
.filterx(new ArrayList2<>(), (project) -> project.hasNature(LangCore.NATURE_ID))
;
ArrayList2<IProject> referencing =
ArrayList2.createFrom(getContext().getAllReferencingBuildConfigs())
.map((buildConfig) -> buildConfig.getProject())
.filterx(new ArrayList2<>(), (project) -> project.hasNature(LangCore.NATURE_ID))
;
boolean firstCall = referenced.isEmpty();
ArrayList2<IProject> allOurProjects = referencing;
allOurProjects.add(getProject());
if(!firstCall) {
return null;
}
try {
EclipseUtils.execute_asCore(monitor, (om) -> {
EclipseJobOperation job = buildManager.requestMultiBuild(om, allOurProjects, false);
if(!runAsynchronousBuild()) {
try {
job.join();
} catch(InterruptedException e) {
throw new OperationCancellation();
}
}
});
return null;
}
catch(OperationCancellation cancel) {
return null;
} catch(CoreException ce) {
if(monitor.isCanceled()) {
// This shouldn't usually happen, a OperationCancellation should have been thrown,
// but sometimes its not wrapped correctly.
return null;
}
EclipseCore.logStatus(ce);
throw ce;
}
}
public boolean runAsynchronousBuild() {
return true;
}
/* ----------------- Clean ----------------- */
protected void deleteProjectBuildMarkers() {
try {
getProject().deleteMarkers(LangCore_Actual.BUILD_PROBLEM_ID, true, IResource.DEPTH_INFINITE);
} catch (CoreException ce) {
EclipseCore.logStatus(ce);
}
}
@Override
protected void clean(IProgressMonitor monitor) throws CoreException {
deleteProjectBuildMarkers();
try {
ProcessBuilder pb = createCleanPB();
doClean(monitor, pb);
} catch (OperationCancellation e) {
// return
} catch (CommonException ce) {
throw EclipseCore.createCoreException(ce);
}
}
protected abstract ProcessBuilder createCleanPB() throws CoreException, CommonException;
protected void doClean(IProgressMonitor pm, ProcessBuilder pb)
throws CoreException, CommonException, OperationCancellation {
getToolManager().newRunBuildToolOperation(pb, EclipseUtils.om(pm)).runProcess();
}
}