aa0de9fd540c44d6234c2a248a9bb85314f56aab
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / core / builder / BatchImageBuilder.java
1 /*******************************************************************************
2  * Copyright (c) 2000, 2003 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 net.sourceforge.phpdt.internal.core.builder;
12
13 import java.util.ArrayList;
14
15 import net.sourceforge.phpdt.core.JavaCore;
16 import net.sourceforge.phpdt.internal.core.JavaModelManager;
17 import net.sourceforge.phpdt.internal.core.util.Util;
18 import net.sourceforge.phpeclipse.PHPeclipsePlugin;
19 import net.sourceforge.phpeclipse.builder.IdentifierIndexManager;
20
21 import org.eclipse.core.resources.IContainer;
22 import org.eclipse.core.resources.IFile;
23 import org.eclipse.core.resources.IResource;
24 import org.eclipse.core.resources.IResourceProxy;
25 import org.eclipse.core.resources.IResourceProxyVisitor;
26 import org.eclipse.core.runtime.CoreException;
27 import org.eclipse.core.runtime.IPath;
28 import net.sourceforge.phpdt.internal.core.builder.PHPBuilder;
29 import net.sourceforge.phpdt.internal.core.builder.SourceFile;
30
31 public class BatchImageBuilder extends AbstractImageBuilder {
32
33 protected BatchImageBuilder(PHPBuilder javaBuilder) {
34         super(javaBuilder);
35         this.nameEnvironment.isIncrementalBuild = false;
36 }
37
38 public void build() {
39         if (PHPBuilder.DEBUG)
40                 System.out.println("FULL build"); //$NON-NLS-1$
41
42         try {
43                 notifier.subTask(Util.bind("build.cleaningOutput")); //$NON-NLS-1$
44                 PHPBuilder.removeProblemsAndTasksFor(javaBuilder.currentProject);
45 //              cleanOutputFolders(true);
46                 notifier.updateProgressDelta(0.1f);
47
48                 notifier.subTask(Util.bind("build.analyzingSources")); //$NON-NLS-1$
49                 ArrayList sourceFiles = new ArrayList(33);
50                 addAllSourceFiles(sourceFiles);
51                 notifier.updateProgressDelta(0.15f);
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
62                 if (javaBuilder.javaProject.hasCycleMarker())
63                         javaBuilder.mustPropagateStructuralChanges();
64                 
65         } catch (CoreException e) {
66                 throw internalException(e);
67         } finally {
68                 cleanUp();
69         }
70 }
71
72 protected void addAllSourceFiles(final ArrayList sourceFiles) throws CoreException {
73     
74         for (int i = 0, l = sourceLocations.length; i < l; i++) {
75                 final ClasspathMultiDirectory sourceLocation = sourceLocations[i];
76                 final char[][] exclusionPatterns = sourceLocation.exclusionPatterns;
77                 final boolean isAlsoProject = sourceLocation.sourceFolder.equals(javaBuilder.currentProject);
78                 sourceLocation.sourceFolder.accept(
79                         new IResourceProxyVisitor() {
80                                 public boolean visit(IResourceProxy proxy) throws CoreException {
81                                         IResource resource = null;
82                                         if (exclusionPatterns != null) {
83                                                 resource = proxy.requestResource();
84                                                 if (Util.isExcluded(resource, exclusionPatterns)) return false;
85                                         }
86                                         switch(proxy.getType()) {
87                                                 case IResource.FILE :
88                                                         if (net.sourceforge.phpdt.internal.compiler.util.Util.isJavaFileName(proxy.getName())) {
89                                                                 if (resource == null)
90                                                                         resource = proxy.requestResource();
91                                                                 sourceFiles.add(new SourceFile((IFile) resource, sourceLocation, encoding));
92                                                         }
93                                                         return false;
94                                                 case IResource.FOLDER :
95                                                         if (isAlsoProject && isExcludedFromProject(proxy.requestFullPath())) return false;
96                                         }
97                                         return true;
98                                 }
99                         },
100                         IResource.NONE
101                 );
102                 notifier.checkCancel();
103         }
104 }
105
106 protected void cleanOutputFolders() throws CoreException {
107         boolean deleteAll = JavaCore.CLEAN.equals(
108                 javaBuilder.javaProject.getOption(JavaCore.CORE_JAVA_BUILD_CLEAN_OUTPUT_FOLDER, true));
109         if (deleteAll) {
110                 ArrayList visited = new ArrayList(sourceLocations.length);
111                 for (int i = 0, l = sourceLocations.length; i < l; i++) {
112                         notifier.subTask(Util.bind("build.cleaningOutput")); //$NON-NLS-1$
113                         ClasspathMultiDirectory sourceLocation = sourceLocations[i];
114                         if (sourceLocation.hasIndependentOutputFolder) {
115                                 IContainer outputFolder = sourceLocation.binaryFolder;
116                                 if (!visited.contains(outputFolder)) {
117                                         visited.add(outputFolder);
118                                         IResource[] members = outputFolder.members(); 
119                                         for (int j = 0, m = members.length; j < m; j++)
120                                                 members[j].delete(IResource.FORCE, null);
121                                 }
122                                 notifier.checkCancel();
123                                 copyExtraResourcesBack(sourceLocation, deleteAll);
124                         } else {
125                                 boolean isOutputFolder = sourceLocation.sourceFolder.equals(sourceLocation.binaryFolder);
126                                 final char[][] exclusionPatterns =
127                                         isOutputFolder
128                                                 ? sourceLocation.exclusionPatterns
129                                                 : null; // ignore exclusionPatterns if output folder == another source folder... not this one
130                                 sourceLocation.binaryFolder.accept(
131                                         new IResourceProxyVisitor() {
132                                                 public boolean visit(IResourceProxy proxy) throws CoreException {
133                                                         IResource resource = null;
134                                                         if (exclusionPatterns != null) {
135                                                                 resource = proxy.requestResource();
136                                                                 if (Util.isExcluded(resource, exclusionPatterns)) return false;
137                                                         }
138                                                         if (proxy.getType() == IResource.FILE) {
139 //                                                              if (Util.isClassFileName(proxy.getName())) {
140 //                                                                      if (resource == null)
141 //                                                                              resource = proxy.requestResource();
142 //                                                                      resource.delete(IResource.FORCE, null);
143 //                                                              }
144                                                                 return false;
145                                                         }
146                                                         notifier.checkCancel();
147                                                         return true;
148                                                 }
149                                         },
150                                         IResource.NONE
151                                 );
152                                 if (!isOutputFolder) {
153                                         notifier.checkCancel();
154                                         copyPackages(sourceLocation);
155                                 }
156                         }
157                         notifier.checkCancel();
158                 }
159         } else {
160                 for (int i = 0, l = sourceLocations.length; i < l; i++) {
161                         ClasspathMultiDirectory sourceLocation = sourceLocations[i];
162                         if (sourceLocation.hasIndependentOutputFolder)
163                                 copyExtraResourcesBack(sourceLocation, deleteAll);
164                         else if (!sourceLocation.sourceFolder.equals(sourceLocation.binaryFolder))
165                                 copyPackages(sourceLocation); // output folder is different from source folder
166                         notifier.checkCancel();
167                 }
168         }
169 }
170
171 protected void copyExtraResourcesBack(ClasspathMultiDirectory sourceLocation, final boolean deletedAll) throws CoreException {
172         // When, if ever, does a builder need to copy resources files (not .java or .class) into the output folder?
173         // If we wipe the output folder at the beginning of the build then all 'extra' resources must be copied to the output folder.
174
175         notifier.subTask(Util.bind("build.copyingResources")); //$NON-NLS-1$
176         final int segmentCount = sourceLocation.sourceFolder.getFullPath().segmentCount();
177         final char[][] exclusionPatterns = sourceLocation.exclusionPatterns;
178         final IContainer outputFolder = sourceLocation.binaryFolder;
179         final boolean isAlsoProject = sourceLocation.sourceFolder.equals(javaBuilder.currentProject);
180         sourceLocation.sourceFolder.accept(
181                 new IResourceProxyVisitor() {
182                         public boolean visit(IResourceProxy proxy) throws CoreException {
183                                 IResource resource = null;
184                                 switch(proxy.getType()) {
185                                         case IResource.FILE :
186                                                 if (net.sourceforge.phpdt.internal.compiler.util.Util.isJavaFileName(proxy.getName())) return false;// || Util.isClassFileName(proxy.getName())) return false;
187
188                                                 resource = proxy.requestResource();
189                                                 if (javaBuilder.filterExtraResource(resource)) return false;
190                                                 if (exclusionPatterns != null && Util.isExcluded(resource, exclusionPatterns))
191                                                         return false;
192
193                                                 IPath partialPath = resource.getFullPath().removeFirstSegments(segmentCount);
194                                                 IResource copiedResource = outputFolder.getFile(partialPath);
195                                                 if (copiedResource.exists()) {
196                                                         if (deletedAll) {
197                                                                 createErrorFor(resource, Util.bind("build.duplicateResource")); //$NON-NLS-1$
198                                                                 return false;
199                                                         }
200                                                         copiedResource.delete(IResource.FORCE, null); // last one wins
201                                                 }
202                                                 resource.copy(copiedResource.getFullPath(), IResource.FORCE, null);
203                                                 copiedResource.setDerived(true);
204                                                 return false;
205                                         case IResource.FOLDER :
206                                                 resource = proxy.requestResource();
207                                                 if (javaBuilder.filterExtraResource(resource)) return false;
208                                                 if (exclusionPatterns != null && Util.isExcluded(resource, exclusionPatterns))
209                                                         return false;
210
211                                                 IPath folderPath = resource.getFullPath();
212                                                 if (isAlsoProject && isExcludedFromProject(folderPath)) return false; // the sourceFolder == project
213                                                 createFolder(folderPath.removeFirstSegments(segmentCount), outputFolder);
214                                 }
215                                 return true;
216                         }
217                 },
218                 IResource.NONE
219         );
220 }
221
222 protected void copyPackages(ClasspathMultiDirectory sourceLocation) throws CoreException {
223         final int segmentCount = sourceLocation.sourceFolder.getFullPath().segmentCount();
224         final char[][] exclusionPatterns = sourceLocation.exclusionPatterns;
225         final IContainer outputFolder = sourceLocation.binaryFolder;
226         final boolean isAlsoProject = sourceLocation.sourceFolder.equals(javaBuilder.currentProject);
227         sourceLocation.sourceFolder.accept(
228                 new IResourceProxyVisitor() {
229                         public boolean visit(IResourceProxy proxy) throws CoreException {
230                                 switch(proxy.getType()) {
231                                         case IResource.FILE :
232                                                 return false;
233                                         case IResource.FOLDER :
234                                                 IResource resource = proxy.requestResource();
235                                                 if (javaBuilder.filterExtraResource(resource)) return false;
236                                                 if (exclusionPatterns != null && Util.isExcluded(resource, exclusionPatterns))
237                                                         return false;
238
239                                                 IPath folderPath = resource.getFullPath();
240                                                 if (isAlsoProject && isExcludedFromProject(folderPath)) return false; // the sourceFolder == project
241                                                 createFolder(folderPath.removeFirstSegments(segmentCount), outputFolder);
242                                 }
243                                 return true;
244                         }
245                 },
246                 IResource.NONE
247         );
248 }
249
250 public String toString() {
251         return "batch image builder for:\n\tnew state: " + newState; //$NON-NLS-1$
252 }
253 }