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