/*******************************************************************************
* Copyright © 2012, 2013 IBM Corporation and others.
* 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:
* IBM Corporation - initial API and implementation
*
*******************************************************************************/
package org.eclipse.edt.ide.core.internal.generation;
import java.util.HashSet;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.core.runtime.IPath;
import org.eclipse.edt.compiler.internal.core.builder.BuildException;
import org.eclipse.edt.compiler.internal.core.builder.CancelledException;
import org.eclipse.edt.compiler.internal.core.builder.IBuildNotifier;
import org.eclipse.edt.ide.core.CoreIDEPluginStrings;
import org.eclipse.edt.ide.core.internal.lookup.ProjectBuildPathManager;
import org.eclipse.edt.ide.core.internal.utils.Util;
import org.eclipse.edt.mof.utils.NameUtile;
/**
* Base generator that processes deltas and kicks off the generation queue.
*/
public abstract class AbstractGenerator {
protected GenerationBuilder builder;
protected IBuildNotifier notifier;
protected IContainer outputLocation;
protected HashSet processedFiles;
protected GenerationQueue generationQueue;
protected AbstractGenerator(GenerationBuilder builder,IBuildNotifier notifier) {
this.builder = builder;
this.notifier = notifier;
this.outputLocation = ProjectBuildPathManager.getInstance().getProjectBuildPath(builder.getProject()).getOutputLocation();
this.processedFiles = new HashSet();
this.generationQueue = new GenerationQueue(notifier, builder.getProject());
}
public boolean build(IResourceDelta sourceDelta) {
boolean abortedBuild = false;
try {
beginBuilding();
if (sourceDelta != null) {
if (!processDeltas(sourceDelta)) {
abortedBuild = true;
}
}
if (!abortedBuild) {
addAdditionalParts();
generationQueue.generate();
abortedBuild = notifier.isAborted();
}
} catch(CancelledException e) {
throw e;
} catch(BuildException e) {
throw e;
} catch(RuntimeException e) {
throw new BuildException(e);
}
return abortedBuild;
}
protected boolean processDeltas(IResourceDelta delta) {
notifier.updateProgressDelta(0.20f);
notifier.subTask(CoreIDEPluginStrings.analyzingChangedIRs);
IResourceDelta sourceDelta = delta.findMember(outputLocation.getProjectRelativePath());
if (sourceDelta != null) {
// TODO Remove this check, or throw exception, since we should never get here...
if (sourceDelta.getKind() == IResourceDelta.REMOVED) {
System.out.println("ABORTING incremental build... found removed bin folder"); //$NON-NLS-1$
return false; // removed source folder should not make it here, but handle anyways (ADDED is supported)
}
int segmentCount = sourceDelta.getFullPath().segmentCount();
IResourceDelta[] children = sourceDelta.getAffectedChildren();
for (int j = 0, m = children.length; j < m; j++) {
processDeltas(children[j], segmentCount);
}
}
notifier.checkCancel();
return true;
}
private void processDeltas(IResourceDelta sourceDelta, int segmentCount) {
IResource resource = sourceDelta.getResource();
switch(resource.getType()) {
case IResource.FOLDER :
switch (sourceDelta.getKind()) {
case IResourceDelta.ADDED:
case IResourceDelta.CHANGED:
IResourceDelta[] children = sourceDelta.getAffectedChildren();
for (int i = 0, l = children.length; i < l; i++){
processDeltas(children[i], segmentCount);
}
break;
case IResourceDelta.REMOVED:
//TODO cleanup generated artifacts?
break;
}
break;
case IResource.FILE:
String resourceName = resource.getName();
processedFiles.add(resource);
if (org.eclipse.edt.compiler.tools.IRUtils.isEGLIRFileName(resourceName)) {
switch (sourceDelta.getKind()) {
case IResourceDelta.CHANGED: // generate even if the content hasn't changed; could be the generator for a file changed
case IResourceDelta.ADDED:
IPath fullPath = resource.getFullPath();
IPath packagePath = fullPath.removeFirstSegments(segmentCount).removeLastSegments(1);
generationQueue.addPart(NameUtile.getAsName(Util.pathToQualifiedName(packagePath)), NameUtile.getAsName(fullPath.removeFileExtension().lastSegment()));
break;
case IResourceDelta.REMOVED:
//TODO cleanup generated artifacts?
break;
}
}
break;
}
}
/**
* Populates the queue with additional parts to generate.
*/
protected abstract void addAdditionalParts();
protected void beginBuilding() {
notifier.setAborted(false); // we may be re-using the notifier, so set this back to false
}
}