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