Source code: org/eclipse/jdt/internal/core/builder/BatchImageBuilder.java
1 /*******************************************************************************
2 * Copyright (c) 2000, 2004 IBM Corporation and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Common Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/cpl-v10.html
7 *
8 * Contributors:
9 * IBM Corporation - initial API and implementation
10 *******************************************************************************/
11 package org.eclipse.jdt.internal.core.builder;
12
13 import org.eclipse.core.resources.*;
14 import org.eclipse.core.runtime.*;
15
16 import org.eclipse.jdt.core.JavaCore;
17 import org.eclipse.jdt.internal.core.util.Util;
18
19 import java.util.*;
20
21 public class BatchImageBuilder extends AbstractImageBuilder {
22
23 protected BatchImageBuilder(JavaBuilder javaBuilder) {
24 super(javaBuilder);
25 this.nameEnvironment.isIncrementalBuild = false;
26 }
27
28 public void build() {
29 if (JavaBuilder.DEBUG)
30 System.out.println("FULL build"); //$NON-NLS-1$
31
32 try {
33 notifier.subTask(Util.bind("build.cleaningOutput")); //$NON-NLS-1$
34 JavaBuilder.removeProblemsAndTasksFor(javaBuilder.currentProject);
35 cleanOutputFolders(true);
36 notifier.updateProgressDelta(0.1f);
37
38 notifier.subTask(Util.bind("build.analyzingSources")); //$NON-NLS-1$
39 ArrayList sourceFiles = new ArrayList(33);
40 addAllSourceFiles(sourceFiles);
41 notifier.updateProgressDelta(0.15f);
42
43 if (sourceFiles.size() > 0) {
44 SourceFile[] allSourceFiles = new SourceFile[sourceFiles.size()];
45 sourceFiles.toArray(allSourceFiles);
46
47 notifier.setProgressPerCompilationUnit(0.75f / allSourceFiles.length);
48 workQueue.addAll(allSourceFiles);
49 compile(allSourceFiles);
50 }
51
52 if (javaBuilder.javaProject.hasCycleMarker())
53 javaBuilder.mustPropagateStructuralChanges();
54 } catch (CoreException e) {
55 throw internalException(e);
56 } finally {
57 cleanUp();
58 }
59 }
60
61 protected void addAllSourceFiles(final ArrayList sourceFiles) throws CoreException {
62 for (int i = 0, l = sourceLocations.length; i < l; i++) {
63 final ClasspathMultiDirectory sourceLocation = sourceLocations[i];
64 final char[][] exclusionPatterns = sourceLocation.exclusionPatterns;
65 final char[][] inclusionPatterns = sourceLocation.inclusionPatterns;
66 final boolean isAlsoProject = sourceLocation.sourceFolder.equals(javaBuilder.currentProject);
67 sourceLocation.sourceFolder.accept(
68 new IResourceProxyVisitor() {
69 public boolean visit(IResourceProxy proxy) throws CoreException {
70 IResource resource = null;
71 switch(proxy.getType()) {
72 case IResource.FILE :
73 if (exclusionPatterns != null || inclusionPatterns != null) {
74 resource = proxy.requestResource();
75 if (Util.isExcluded(resource, inclusionPatterns, exclusionPatterns)) return false;
76 }
77 if (org.eclipse.jdt.internal.compiler.util.Util.isJavaFileName(proxy.getName())) {
78 if (resource == null)
79 resource = proxy.requestResource();
80 sourceFiles.add(new SourceFile((IFile) resource, sourceLocation));
81 }
82 return false;
83 case IResource.FOLDER :
84 if (exclusionPatterns != null && inclusionPatterns == null) {
85 // if there are inclusion patterns then we must walk the children
86 resource = proxy.requestResource();
87 if (Util.isExcluded(resource, inclusionPatterns, exclusionPatterns)) return false;
88 }
89 if (isAlsoProject && isExcludedFromProject(proxy.requestFullPath())) return false;
90 }
91 return true;
92 }
93 },
94 IResource.NONE
95 );
96 notifier.checkCancel();
97 }
98 }
99
100 protected void cleanOutputFolders(boolean copyBack) throws CoreException {
101 boolean deleteAll = JavaCore.CLEAN.equals(
102 javaBuilder.javaProject.getOption(JavaCore.CORE_JAVA_BUILD_CLEAN_OUTPUT_FOLDER, true));
103 if (deleteAll) {
104 ArrayList visited = new ArrayList(sourceLocations.length);
105 for (int i = 0, l = sourceLocations.length; i < l; i++) {
106 notifier.subTask(Util.bind("build.cleaningOutput")); //$NON-NLS-1$
107 ClasspathMultiDirectory sourceLocation = sourceLocations[i];
108 if (sourceLocation.hasIndependentOutputFolder) {
109 IContainer outputFolder = sourceLocation.binaryFolder;
110 if (!visited.contains(outputFolder)) {
111 visited.add(outputFolder);
112 IResource[] members = outputFolder.members();
113 for (int j = 0, m = members.length; j < m; j++) {
114 IResource member = members[j];
115 if (!member.isDerived()) {
116 member.accept(
117 new IResourceVisitor() {
118 public boolean visit(IResource resource) throws CoreException {
119 resource.setDerived(true);
120 return resource.getType() != IResource.FILE;
121 }
122 }
123 );
124 }
125 member.delete(IResource.FORCE, null);
126 }
127 }
128 notifier.checkCancel();
129 if (copyBack)
130 copyExtraResourcesBack(sourceLocation, true);
131 } else {
132 boolean isOutputFolder = sourceLocation.sourceFolder.equals(sourceLocation.binaryFolder);
133 final char[][] exclusionPatterns =
134 isOutputFolder
135 ? sourceLocation.exclusionPatterns
136 : null; // ignore exclusionPatterns if output folder == another source folder... not this one
137 final char[][] inclusionPatterns =
138 isOutputFolder
139 ? sourceLocation.inclusionPatterns
140 : null; // ignore inclusionPatterns if output folder == another source folder... not this one
141 sourceLocation.binaryFolder.accept(
142 new IResourceProxyVisitor() {
143 public boolean visit(IResourceProxy proxy) throws CoreException {
144 IResource resource = null;
145 if (proxy.getType() == IResource.FILE) {
146 if (exclusionPatterns != null || inclusionPatterns != null) {
147 resource = proxy.requestResource();
148 if (Util.isExcluded(resource, inclusionPatterns, exclusionPatterns)) return false;
149 }
150 if (org.eclipse.jdt.internal.compiler.util.Util.isClassFileName(proxy.getName())) {
151 if (resource == null)
152 resource = proxy.requestResource();
153 resource.delete(IResource.FORCE, null);
154 }
155 return false;
156 }
157 if (exclusionPatterns != null && inclusionPatterns == null) {
158 // if there are inclusion patterns then we must walk the children
159 resource = proxy.requestResource();
160 if (Util.isExcluded(resource, inclusionPatterns, exclusionPatterns)) return false;
161 }
162 notifier.checkCancel();
163 return true;
164 }
165 },
166 IResource.NONE
167 );
168 if (!isOutputFolder && copyBack) {
169 notifier.checkCancel();
170 copyPackages(sourceLocation);
171 }
172 }
173 notifier.checkCancel();
174 }
175 } else if (copyBack) {
176 for (int i = 0, l = sourceLocations.length; i < l; i++) {
177 ClasspathMultiDirectory sourceLocation = sourceLocations[i];
178 if (sourceLocation.hasIndependentOutputFolder)
179 copyExtraResourcesBack(sourceLocation, false);
180 else if (!sourceLocation.sourceFolder.equals(sourceLocation.binaryFolder))
181 copyPackages(sourceLocation); // output folder is different from source folder
182 notifier.checkCancel();
183 }
184 }
185 }
186
187 protected void copyExtraResourcesBack(ClasspathMultiDirectory sourceLocation, final boolean deletedAll) throws CoreException {
188 // When, if ever, does a builder need to copy resources files (not .java or .class) into the output folder?
189 // If we wipe the output folder at the beginning of the build then all 'extra' resources must be copied to the output folder.
190
191 notifier.subTask(Util.bind("build.copyingResources")); //$NON-NLS-1$
192 final int segmentCount = sourceLocation.sourceFolder.getFullPath().segmentCount();
193 final char[][] exclusionPatterns = sourceLocation.exclusionPatterns;
194 final char[][] inclusionPatterns = sourceLocation.inclusionPatterns;
195 final IContainer outputFolder = sourceLocation.binaryFolder;
196 final boolean isAlsoProject = sourceLocation.sourceFolder.equals(javaBuilder.currentProject);
197 sourceLocation.sourceFolder.accept(
198 new IResourceProxyVisitor() {
199 public boolean visit(IResourceProxy proxy) throws CoreException {
200 IResource resource = null;
201 switch(proxy.getType()) {
202 case IResource.FILE :
203 if (org.eclipse.jdt.internal.compiler.util.Util.isJavaFileName(proxy.getName()) ||
204 org.eclipse.jdt.internal.compiler.util.Util.isClassFileName(proxy.getName())) return false;
205
206 resource = proxy.requestResource();
207 if (javaBuilder.filterExtraResource(resource)) return false;
208 if (exclusionPatterns != null || inclusionPatterns != null)
209 if (Util.isExcluded(resource, inclusionPatterns, exclusionPatterns))
210 return false;
211
212 IPath partialPath = resource.getFullPath().removeFirstSegments(segmentCount);
213 IResource copiedResource = outputFolder.getFile(partialPath);
214 if (copiedResource.exists()) {
215 if (deletedAll) {
216 IResource originalResource = findOriginalResource(partialPath);
217 String id = originalResource.getFullPath().removeFirstSegments(1).toString();
218 createProblemFor(
219 resource,
220 Util.bind("build.duplicateResource", id), //$NON-NLS-1$
221 javaBuilder.javaProject.getOption(JavaCore.CORE_JAVA_BUILD_DUPLICATE_RESOURCE, true));
222 return false;
223 }
224 copiedResource.delete(IResource.FORCE, null); // last one wins
225 }
226 resource.copy(copiedResource.getFullPath(), IResource.FORCE, null);
227 copiedResource.setDerived(true);
228 copiedResource.setReadOnly(false); // just in case the original was read only
229 return false;
230 case IResource.FOLDER :
231 resource = proxy.requestResource();
232 if (javaBuilder.filterExtraResource(resource)) return false;
233 IPath folderPath = resource.getFullPath();
234 if (isAlsoProject && isExcludedFromProject(folderPath)) return false; // the sourceFolder == project
235 if (exclusionPatterns != null && Util.isExcluded(resource, inclusionPatterns, exclusionPatterns))
236 return inclusionPatterns != null; // need to go further only if inclusionPatterns are set
237 createFolder(folderPath.removeFirstSegments(segmentCount), outputFolder);
238 }
239 return true;
240 }
241 },
242 IResource.NONE
243 );
244 }
245
246 protected void copyPackages(ClasspathMultiDirectory sourceLocation) throws CoreException {
247 final int segmentCount = sourceLocation.sourceFolder.getFullPath().segmentCount();
248 final char[][] exclusionPatterns = sourceLocation.exclusionPatterns;
249 final char[][] inclusionPatterns = sourceLocation.inclusionPatterns;
250 final IContainer outputFolder = sourceLocation.binaryFolder;
251 final boolean isAlsoProject = sourceLocation.sourceFolder.equals(javaBuilder.currentProject);
252 sourceLocation.sourceFolder.accept(
253 new IResourceProxyVisitor() {
254 public boolean visit(IResourceProxy proxy) throws CoreException {
255 switch(proxy.getType()) {
256 case IResource.FILE :
257 return false;
258 case IResource.FOLDER :
259 IResource resource = proxy.requestResource();
260 if (javaBuilder.filterExtraResource(resource)) return false;
261 IPath folderPath = resource.getFullPath();
262 if (isAlsoProject && isExcludedFromProject(folderPath)) return false; // the sourceFolder == project
263 if (exclusionPatterns != null && Util.isExcluded(resource, inclusionPatterns, exclusionPatterns))
264 return inclusionPatterns != null; // need to go further only if inclusionPatterns are set
265 createFolder(folderPath.removeFirstSegments(segmentCount), outputFolder);
266 }
267 return true;
268 }
269 },
270 IResource.NONE
271 );
272 }
273
274 protected IResource findOriginalResource(IPath partialPath) {
275 for (int i = 0, l = sourceLocations.length; i < l; i++) {
276 ClasspathMultiDirectory sourceLocation = sourceLocations[i];
277 if (sourceLocation.hasIndependentOutputFolder) {
278 IResource originalResource = sourceLocation.sourceFolder.getFile(partialPath);
279 if (originalResource.exists()) return originalResource;
280 }
281 }
282 return null;
283 }
284
285 public String toString() {
286 return "batch image builder for:\n\tnew state: " + newState; //$NON-NLS-1$
287 }
288 }