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