KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > core > builder > BatchImageBuilder


1 /*******************************************************************************
2  * Copyright (c) 2000, 2007 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-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.core.compiler.*;
18 import org.eclipse.jdt.internal.compiler.ClassFile;
19 import org.eclipse.jdt.internal.core.util.Messages;
20 import org.eclipse.jdt.internal.core.util.Util;
21
22 import java.util.*;
23
24 public class BatchImageBuilder extends AbstractImageBuilder {
25
26     IncrementalImageBuilder incrementalBuilder; // if annotations or secondary types have to be processed after the compile loop
27
ArrayList secondaryTypes; // qualified names for all secondary types found during batch compile
28
StringSet typeLocatorsWithUndefinedTypes; // type locators for all source files with errors that may be caused by 'not found' secondary types
29

30 protected BatchImageBuilder(JavaBuilder javaBuilder, boolean buildStarting) {
31     super(javaBuilder, buildStarting, null);
32     this.nameEnvironment.isIncrementalBuild = false;
33     this.incrementalBuilder = null;
34     this.secondaryTypes = null;
35     this.typeLocatorsWithUndefinedTypes = null;
36 }
37
38 public void build() {
39     if (JavaBuilder.DEBUG)
40         System.out.println("FULL build"); //$NON-NLS-1$
41

42     try {
43         notifier.subTask(Messages.bind(Messages.build_cleaningOutput, this.javaBuilder.currentProject.getName()));
44         JavaBuilder.removeProblemsAndTasksFor(javaBuilder.currentProject);
45         cleanOutputFolders(true);
46         notifier.updateProgressDelta(0.05f);
47
48         notifier.subTask(Messages.build_analyzingSources);
49         ArrayList sourceFiles = new ArrayList(33);
50         addAllSourceFiles(sourceFiles);
51         notifier.updateProgressDelta(0.10f);
52
53         if (sourceFiles.size() > 0) {
54             SourceFile[] allSourceFiles = new SourceFile[sourceFiles.size()];
55             sourceFiles.toArray(allSourceFiles);
56
57             notifier.setProgressPerCompilationUnit(0.75f / allSourceFiles.length);
58             workQueue.addAll(allSourceFiles);
59             compile(allSourceFiles);
60
61             if (this.typeLocatorsWithUndefinedTypes != null)
62                 if (this.secondaryTypes != null && !this.secondaryTypes.isEmpty())
63                     rebuildTypesAffectedBySecondaryTypes();
64             if (this.incrementalBuilder != null)
65                 this.incrementalBuilder.buildAfterBatchBuild();
66         }
67
68         if (javaBuilder.javaProject.hasCycleMarker())
69             javaBuilder.mustPropagateStructuralChanges();
70     } catch (CoreException e) {
71         throw internalException(e);
72     } finally {
73         cleanUp();
74     }
75 }
76
77 protected void acceptSecondaryType(ClassFile classFile) {
78     if (this.secondaryTypes != null)
79         this.secondaryTypes.add(classFile.fileName());
80 }
81
82 protected void cleanOutputFolders(boolean copyBack) throws CoreException {
83     boolean deleteAll = JavaCore.CLEAN.equals(
84         javaBuilder.javaProject.getOption(JavaCore.CORE_JAVA_BUILD_CLEAN_OUTPUT_FOLDER, true));
85     if (deleteAll) {
86         if (this.javaBuilder.participants != null)
87             for (int i = 0, l = this.javaBuilder.participants.length; i < l; i++)
88                 this.javaBuilder.participants[i].cleanStarting(this.javaBuilder.javaProject);
89
90         ArrayList visited = new ArrayList(sourceLocations.length);
91         for (int i = 0, l = sourceLocations.length; i < l; i++) {
92             notifier.subTask(Messages.bind(Messages.build_cleaningOutput, this.javaBuilder.currentProject.getName()));
93             ClasspathMultiDirectory sourceLocation = sourceLocations[i];
94             if (sourceLocation.hasIndependentOutputFolder) {
95                 IContainer outputFolder = sourceLocation.binaryFolder;
96                 if (!visited.contains(outputFolder)) {
97                     visited.add(outputFolder);
98                     IResource[] members = outputFolder.members();
99                     for (int j = 0, m = members.length; j < m; j++) {
100                         IResource member = members[j];
101                         if (!member.isDerived()) {
102                             member.accept(
103                                 new IResourceVisitor() {
104                                     public boolean visit(IResource resource) throws CoreException {
105                                         resource.setDerived(true);
106                                         return resource.getType() != IResource.FILE;
107                                     }
108                                 }
109                             );
110                         }
111                         member.delete(IResource.FORCE, null);
112                     }
113                 }
114                 notifier.checkCancel();
115                 if (copyBack)
116                     copyExtraResourcesBack(sourceLocation, true);
117             } else {
118                 boolean isOutputFolder = sourceLocation.sourceFolder.equals(sourceLocation.binaryFolder);
119                 final char[][] exclusionPatterns =
120                     isOutputFolder
121                         ? sourceLocation.exclusionPatterns
122                         : null; // ignore exclusionPatterns if output folder == another source folder... not this one
123
final char[][] inclusionPatterns =
124                     isOutputFolder
125                         ? sourceLocation.inclusionPatterns
126                         : null; // ignore inclusionPatterns if output folder == another source folder... not this one
127
sourceLocation.binaryFolder.accept(
128                     new IResourceProxyVisitor() {
129                         public boolean visit(IResourceProxy proxy) throws CoreException {
130                             if (proxy.getType() == IResource.FILE) {
131                                 if (org.eclipse.jdt.internal.compiler.util.Util.isClassFileName(proxy.getName())) {
132                                     IResource resource = proxy.requestResource();
133                                     if (exclusionPatterns != null || inclusionPatterns != null)
134                                         if (Util.isExcluded(resource.getFullPath(), inclusionPatterns, exclusionPatterns, false))
135                                             return false;
136                                     resource.delete(IResource.FORCE, null);
137                                 }
138                                 return false;
139                             }
140                             if (exclusionPatterns != null && inclusionPatterns == null) // must walk children if inclusionPatterns != null
141
if (Util.isExcluded(proxy.requestFullPath(), null, exclusionPatterns, true))
142                                     return false;
143                             notifier.checkCancel();
144                             return true;
145                         }
146                     },
147                     IResource.NONE
148                 );
149                 notifier.checkCancel();
150             }
151             notifier.checkCancel();
152         }
153     } else if (copyBack) {
154         for (int i = 0, l = sourceLocations.length; i < l; i++) {
155             ClasspathMultiDirectory sourceLocation = sourceLocations[i];
156             if (sourceLocation.hasIndependentOutputFolder)
157                 copyExtraResourcesBack(sourceLocation, false);
158             notifier.checkCancel();
159         }
160     }
161 }
162
163 protected void cleanUp() {
164     this.incrementalBuilder = null;
165     this.secondaryTypes = null;
166     this.typeLocatorsWithUndefinedTypes = null;
167     super.cleanUp();
168 }
169
170 protected void compile(SourceFile[] units, SourceFile[] additionalUnits, boolean compilingFirstGroup) {
171     if (additionalUnits != null && this.secondaryTypes == null)
172         this.secondaryTypes = new ArrayList(7);
173     super.compile(units, additionalUnits, compilingFirstGroup);
174 }
175
176 protected void copyExtraResourcesBack(ClasspathMultiDirectory sourceLocation, final boolean deletedAll) throws CoreException {
177     // When, if ever, does a builder need to copy resources files (not .java or .class) into the output folder?
178
// If we wipe the output folder at the beginning of the build then all 'extra' resources must be copied to the output folder.
179

180     notifier.subTask(Messages.build_copyingResources);
181     final int segmentCount = sourceLocation.sourceFolder.getFullPath().segmentCount();
182     final char[][] exclusionPatterns = sourceLocation.exclusionPatterns;
183     final char[][] inclusionPatterns = sourceLocation.inclusionPatterns;
184     final IContainer outputFolder = sourceLocation.binaryFolder;
185     final boolean isAlsoProject = sourceLocation.sourceFolder.equals(javaBuilder.currentProject);
186     sourceLocation.sourceFolder.accept(
187         new IResourceProxyVisitor() {
188             public boolean visit(IResourceProxy proxy) throws CoreException {
189                 IResource resource = null;
190                 switch(proxy.getType()) {
191                     case IResource.FILE :
192                         if (org.eclipse.jdt.internal.core.util.Util.isJavaLikeFileName(proxy.getName()) ||
193                             org.eclipse.jdt.internal.compiler.util.Util.isClassFileName(proxy.getName())) return false;
194
195                         resource = proxy.requestResource();
196                         if (javaBuilder.filterExtraResource(resource)) return false;
197                         if (exclusionPatterns != null || inclusionPatterns != null)
198                             if (Util.isExcluded(resource.getFullPath(), inclusionPatterns, exclusionPatterns, false))
199                                 return false;
200
201                         IPath partialPath = resource.getFullPath().removeFirstSegments(segmentCount);
202                         IResource copiedResource = outputFolder.getFile(partialPath);
203                         if (copiedResource.exists()) {
204                             if (deletedAll) {
205                                 IResource originalResource = findOriginalResource(partialPath);
206                                 String JavaDoc id = originalResource.getFullPath().removeFirstSegments(1).toString();
207                                 createProblemFor(
208                                     resource,
209                                     null,
210                                     Messages.bind(Messages.build_duplicateResource, id),
211                                     javaBuilder.javaProject.getOption(JavaCore.CORE_JAVA_BUILD_DUPLICATE_RESOURCE, true));
212                                 return false;
213                             }
214                             copiedResource.delete(IResource.FORCE, null); // last one wins
215
}
216                         createFolder(partialPath.removeLastSegments(1), outputFolder); // ensure package folder exists
217
resource.copy(copiedResource.getFullPath(), IResource.FORCE | IResource.DERIVED, null);
218                         Util.setReadOnly(copiedResource, false); // just in case the original was read only
219
return false;
220                     case IResource.FOLDER :
221                         resource = proxy.requestResource();
222                         if (javaBuilder.filterExtraResource(resource)) return false;
223                         if (isAlsoProject && isExcludedFromProject(resource.getFullPath())) return false; // the sourceFolder == project
224
if (exclusionPatterns != null && inclusionPatterns == null) // must walk children if inclusionPatterns != null
225
if (Util.isExcluded(resource.getFullPath(), null, exclusionPatterns, true))
226                                 return false;
227                 }
228                 return true;
229             }
230         },
231         IResource.NONE
232     );
233 }
234
235 protected IResource findOriginalResource(IPath partialPath) {
236     for (int i = 0, l = sourceLocations.length; i < l; i++) {
237         ClasspathMultiDirectory sourceLocation = sourceLocations[i];
238         if (sourceLocation.hasIndependentOutputFolder) {
239             IResource originalResource = sourceLocation.sourceFolder.getFile(partialPath);
240             if (originalResource.exists()) return originalResource;
241         }
242     }
243     return null;
244 }
245
246 protected void processAnnotationResults(CompilationParticipantResult[] results) {
247     // to compile the compilation participant results, we need to incrementally recompile all affected types
248
// whenever the generated types are initially added or structurally changed
249
if (this.incrementalBuilder == null)
250         this.incrementalBuilder = new IncrementalImageBuilder(this);
251     this.incrementalBuilder.processAnnotationResults(results);
252 }
253
254 protected void rebuildTypesAffectedBySecondaryTypes() {
255     // to compile types that could not find 'missing' secondary types because of multiple
256
// compile groups, we need to incrementally recompile all affected types as if the missing
257
// secondary types have just been added, see bug 146324
258
if (this.incrementalBuilder == null)
259         this.incrementalBuilder = new IncrementalImageBuilder(this);
260
261     for (int i = this.secondaryTypes.size(); --i >=0;) {
262         char[] secondaryTypeName = (char[]) this.secondaryTypes.get(i);
263         IPath path = new Path(null, new String JavaDoc(secondaryTypeName));
264         this.incrementalBuilder.addDependentsOf(path, false);
265     }
266     this.incrementalBuilder.addAffectedSourceFiles(
267         this.incrementalBuilder.qualifiedStrings,
268         this.incrementalBuilder.simpleStrings,
269         this.typeLocatorsWithUndefinedTypes);
270 }
271
272 protected void storeProblemsFor(SourceFile sourceFile, CategorizedProblem[] problems) throws CoreException {
273     if (sourceFile == null || problems == null || problems.length == 0) return;
274
275     for (int i = problems.length; --i >= 0;) {
276         CategorizedProblem problem = problems[i];
277         if (problem != null && problem.getID() == IProblem.UndefinedType) {
278             if (this.typeLocatorsWithUndefinedTypes == null)
279                 this.typeLocatorsWithUndefinedTypes = new StringSet(3);
280             this.typeLocatorsWithUndefinedTypes.add(sourceFile.typeLocator());
281             break;
282         }
283     }
284
285     super.storeProblemsFor(sourceFile, problems);
286 }
287
288 public String JavaDoc toString() {
289     return "batch image builder for:\n\tnew state: " + newState; //$NON-NLS-1$
290
}
291 }
292
Popular Tags