blob: b6237209919673755b92decc937cd173538218ff [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2004 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.jdt.internal.core.builder;
import org.eclipse.core.resources.*;
import org.eclipse.core.runtime.*;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.internal.core.util.Messages;
import org.eclipse.jdt.internal.core.util.Util;
import java.util.*;
public class BatchImageBuilder extends AbstractImageBuilder {
protected BatchImageBuilder(JavaBuilder javaBuilder) {
super(javaBuilder);
this.nameEnvironment.isIncrementalBuild = false;
}
public void build() {
if (JavaBuilder.DEBUG)
System.out.println("FULL build"); //$NON-NLS-1$
try {
notifier.subTask(Messages.build_cleaningOutput);
JavaBuilder.removeProblemsAndTasksFor(javaBuilder.currentProject);
cleanOutputFolders(true);
notifier.updateProgressDelta(0.1f);
notifier.subTask(Messages.build_analyzingSources);
ArrayList sourceFiles = new ArrayList(33);
addAllSourceFiles(sourceFiles);
notifier.updateProgressDelta(0.15f);
if (sourceFiles.size() > 0) {
SourceFile[] allSourceFiles = new SourceFile[sourceFiles.size()];
sourceFiles.toArray(allSourceFiles);
notifier.setProgressPerCompilationUnit(0.75f / allSourceFiles.length);
workQueue.addAll(allSourceFiles);
compile(allSourceFiles);
}
if (javaBuilder.javaProject.hasCycleMarker())
javaBuilder.mustPropagateStructuralChanges();
} catch (CoreException e) {
throw internalException(e);
} finally {
cleanUp();
}
}
protected void addAllSourceFiles(final ArrayList sourceFiles) throws CoreException {
for (int i = 0, l = sourceLocations.length; i < l; i++) {
final ClasspathMultiDirectory sourceLocation = sourceLocations[i];
final char[][] exclusionPatterns = sourceLocation.exclusionPatterns;
final char[][] inclusionPatterns = sourceLocation.inclusionPatterns;
final boolean isAlsoProject = sourceLocation.sourceFolder.equals(javaBuilder.currentProject);
sourceLocation.sourceFolder.accept(
new IResourceProxyVisitor() {
public boolean visit(IResourceProxy proxy) throws CoreException {
IResource resource = null;
switch(proxy.getType()) {
case IResource.FILE :
if (exclusionPatterns != null || inclusionPatterns != null) {
resource = proxy.requestResource();
if (Util.isExcluded(resource, inclusionPatterns, exclusionPatterns)) return false;
}
if (org.eclipse.jdt.internal.core.util.Util.isJavaLikeFileName(proxy.getName())) {
if (resource == null)
resource = proxy.requestResource();
sourceFiles.add(new SourceFile((IFile) resource, sourceLocation));
}
return false;
case IResource.FOLDER :
if (exclusionPatterns != null && inclusionPatterns == null) {
// if there are inclusion patterns then we must walk the children
resource = proxy.requestResource();
if (Util.isExcluded(resource, inclusionPatterns, exclusionPatterns)) return false;
}
if (isAlsoProject && isExcludedFromProject(proxy.requestFullPath())) return false;
}
return true;
}
},
IResource.NONE
);
notifier.checkCancel();
}
}
protected void cleanOutputFolders(boolean copyBack) throws CoreException {
boolean deleteAll = JavaCore.CLEAN.equals(
javaBuilder.javaProject.getOption(JavaCore.CORE_JAVA_BUILD_CLEAN_OUTPUT_FOLDER, true));
if (deleteAll) {
ArrayList visited = new ArrayList(sourceLocations.length);
for (int i = 0, l = sourceLocations.length; i < l; i++) {
notifier.subTask(Messages.build_cleaningOutput);
ClasspathMultiDirectory sourceLocation = sourceLocations[i];
if (sourceLocation.hasIndependentOutputFolder) {
IContainer outputFolder = sourceLocation.binaryFolder;
if (!visited.contains(outputFolder)) {
visited.add(outputFolder);
IResource[] members = outputFolder.members();
for (int j = 0, m = members.length; j < m; j++) {
IResource member = members[j];
if (!member.isDerived()) {
member.accept(
new IResourceVisitor() {
public boolean visit(IResource resource) throws CoreException {
resource.setDerived(true);
return resource.getType() != IResource.FILE;
}
}
);
}
member.delete(IResource.FORCE, null);
}
}
notifier.checkCancel();
if (copyBack)
copyExtraResourcesBack(sourceLocation, true);
} else {
boolean isOutputFolder = sourceLocation.sourceFolder.equals(sourceLocation.binaryFolder);
final char[][] exclusionPatterns =
isOutputFolder
? sourceLocation.exclusionPatterns
: null; // ignore exclusionPatterns if output folder == another source folder... not this one
final char[][] inclusionPatterns =
isOutputFolder
? sourceLocation.inclusionPatterns
: null; // ignore inclusionPatterns if output folder == another source folder... not this one
sourceLocation.binaryFolder.accept(
new IResourceProxyVisitor() {
public boolean visit(IResourceProxy proxy) throws CoreException {
IResource resource = null;
if (proxy.getType() == IResource.FILE) {
if (exclusionPatterns != null || inclusionPatterns != null) {
resource = proxy.requestResource();
if (Util.isExcluded(resource, inclusionPatterns, exclusionPatterns)) return false;
}
if (org.eclipse.jdt.internal.compiler.util.Util.isClassFileName(proxy.getName())) {
if (resource == null)
resource = proxy.requestResource();
resource.delete(IResource.FORCE, null);
}
return false;
}
if (exclusionPatterns != null && inclusionPatterns == null) {
// if there are inclusion patterns then we must walk the children
resource = proxy.requestResource();
if (Util.isExcluded(resource, inclusionPatterns, exclusionPatterns)) return false;
}
notifier.checkCancel();
return true;
}
},
IResource.NONE
);
if (!isOutputFolder && copyBack) {
notifier.checkCancel();
copyPackages(sourceLocation);
}
}
notifier.checkCancel();
}
} else if (copyBack) {
for (int i = 0, l = sourceLocations.length; i < l; i++) {
ClasspathMultiDirectory sourceLocation = sourceLocations[i];
if (sourceLocation.hasIndependentOutputFolder)
copyExtraResourcesBack(sourceLocation, false);
else if (!sourceLocation.sourceFolder.equals(sourceLocation.binaryFolder))
copyPackages(sourceLocation); // output folder is different from source folder
notifier.checkCancel();
}
}
}
protected void copyExtraResourcesBack(ClasspathMultiDirectory sourceLocation, final boolean deletedAll) throws CoreException {
// When, if ever, does a builder need to copy resources files (not .java or .class) into the output folder?
// If we wipe the output folder at the beginning of the build then all 'extra' resources must be copied to the output folder.
notifier.subTask(Messages.build_copyingResources);
final int segmentCount = sourceLocation.sourceFolder.getFullPath().segmentCount();
final char[][] exclusionPatterns = sourceLocation.exclusionPatterns;
final char[][] inclusionPatterns = sourceLocation.inclusionPatterns;
final IContainer outputFolder = sourceLocation.binaryFolder;
final boolean isAlsoProject = sourceLocation.sourceFolder.equals(javaBuilder.currentProject);
sourceLocation.sourceFolder.accept(
new IResourceProxyVisitor() {
public boolean visit(IResourceProxy proxy) throws CoreException {
IResource resource = null;
switch(proxy.getType()) {
case IResource.FILE :
if (org.eclipse.jdt.internal.core.util.Util.isJavaLikeFileName(proxy.getName()) ||
org.eclipse.jdt.internal.compiler.util.Util.isClassFileName(proxy.getName())) return false;
resource = proxy.requestResource();
if (javaBuilder.filterExtraResource(resource)) return false;
if (exclusionPatterns != null || inclusionPatterns != null)
if (Util.isExcluded(resource, inclusionPatterns, exclusionPatterns))
return false;
IPath partialPath = resource.getFullPath().removeFirstSegments(segmentCount);
IResource copiedResource = outputFolder.getFile(partialPath);
if (copiedResource.exists()) {
if (deletedAll) {
IResource originalResource = findOriginalResource(partialPath);
String id = originalResource.getFullPath().removeFirstSegments(1).toString();
createProblemFor(
resource,
null,
Messages.bind(Messages.build_duplicateResource, (new String[] {id})),
javaBuilder.javaProject.getOption(JavaCore.CORE_JAVA_BUILD_DUPLICATE_RESOURCE, true));
return false;
}
copiedResource.delete(IResource.FORCE, null); // last one wins
}
resource.copy(copiedResource.getFullPath(), IResource.FORCE, null);
copiedResource.setDerived(true);
Util.setReadOnly(copiedResource, false); // just in case the original was read only
return false;
case IResource.FOLDER :
resource = proxy.requestResource();
if (javaBuilder.filterExtraResource(resource)) return false;
IPath folderPath = resource.getFullPath();
if (isAlsoProject && isExcludedFromProject(folderPath)) return false; // the sourceFolder == project
if (exclusionPatterns != null && Util.isExcluded(resource, inclusionPatterns, exclusionPatterns))
return inclusionPatterns != null; // need to go further only if inclusionPatterns are set
createFolder(folderPath.removeFirstSegments(segmentCount), outputFolder);
}
return true;
}
},
IResource.NONE
);
}
protected void copyPackages(ClasspathMultiDirectory sourceLocation) throws CoreException {
final int segmentCount = sourceLocation.sourceFolder.getFullPath().segmentCount();
final char[][] exclusionPatterns = sourceLocation.exclusionPatterns;
final char[][] inclusionPatterns = sourceLocation.inclusionPatterns;
final IContainer outputFolder = sourceLocation.binaryFolder;
final boolean isAlsoProject = sourceLocation.sourceFolder.equals(javaBuilder.currentProject);
sourceLocation.sourceFolder.accept(
new IResourceProxyVisitor() {
public boolean visit(IResourceProxy proxy) throws CoreException {
switch(proxy.getType()) {
case IResource.FILE :
return false;
case IResource.FOLDER :
IResource resource = proxy.requestResource();
if (javaBuilder.filterExtraResource(resource)) return false;
IPath folderPath = resource.getFullPath();
if (isAlsoProject && isExcludedFromProject(folderPath)) return false; // the sourceFolder == project
if (exclusionPatterns != null && Util.isExcluded(resource, inclusionPatterns, exclusionPatterns))
return inclusionPatterns != null; // need to go further only if inclusionPatterns are set
createFolder(folderPath.removeFirstSegments(segmentCount), outputFolder);
}
return true;
}
},
IResource.NONE
);
}
protected IResource findOriginalResource(IPath partialPath) {
for (int i = 0, l = sourceLocations.length; i < l; i++) {
ClasspathMultiDirectory sourceLocation = sourceLocations[i];
if (sourceLocation.hasIndependentOutputFolder) {
IResource originalResource = sourceLocation.sourceFolder.getFile(partialPath);
if (originalResource.exists()) return originalResource;
}
}
return null;
}
public String toString() {
return "batch image builder for:\n\tnew state: " + newState; //$NON-NLS-1$
}
}