new version with WorkingCopy Management
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpeclipse / builder / PHPBuilder.java
1 package net.sourceforge.phpeclipse.builder;
2
3 import java.io.DataInputStream;
4 import java.io.DataOutputStream;
5 import java.io.IOException;
6 import java.util.Map;
7
8 import net.sourceforge.phpdt.core.IJavaModelMarker;
9 import net.sourceforge.phpdt.internal.core.JavaProject;
10 import net.sourceforge.phpdt.internal.core.util.SimpleLookupTable;
11 import net.sourceforge.phpdt.internal.ui.util.PHPFileUtil;
12 import net.sourceforge.phpeclipse.PHPeclipsePlugin;
13 import net.sourceforge.phpeclipse.phpeditor.PHPParserAction;
14
15 import org.eclipse.core.resources.IFile;
16 import org.eclipse.core.resources.IMarker;
17 import org.eclipse.core.resources.IProject;
18 import org.eclipse.core.resources.IResource;
19 import org.eclipse.core.resources.IResourceDelta;
20 import org.eclipse.core.resources.IResourceVisitor;
21 import org.eclipse.core.resources.IWorkspaceRoot;
22 import org.eclipse.core.resources.IncrementalProjectBuilder;
23 import org.eclipse.core.runtime.CoreException;
24 import org.eclipse.core.runtime.IConfigurationElement;
25 import org.eclipse.core.runtime.IProgressMonitor;
26 import org.eclipse.core.runtime.OperationCanceledException;
27
28 /**
29  * Builder for .php files. 
30  * 
31  * 
32  * @see org.eclipse.core.resources.IncrementalProjectBuilder
33  * @see org.eclipse.core.resources.IResourceDelta
34  */
35 public class PHPBuilder extends IncrementalProjectBuilder {
36   IProject currentProject;
37   JavaProject javaProject;
38   IWorkspaceRoot workspaceRoot;
39   //    NameEnvironment nameEnvironment;
40   SimpleLookupTable binaryLocationsPerProject;
41   // maps a project to its binary resources (output folders, class folders, zip/jar files)
42   State lastState;
43   
44 //      BuildNotifier notifier;
45         
46   private final static int TOTAL_WORK = 100;
47
48   public static IMarker[] getProblemsFor(IResource resource) {
49     try {
50       if (resource != null && resource.exists())
51         return resource.findMarkers(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER, false, IResource.DEPTH_INFINITE);
52     } catch (CoreException e) {
53     } // assume there are no problems
54     return new IMarker[0];
55   }
56
57   public static IMarker[] getTasksFor(IResource resource) {
58     try {
59       if (resource != null && resource.exists())
60         return resource.findMarkers(IJavaModelMarker.TASK_MARKER, false, IResource.DEPTH_INFINITE);
61     } catch (CoreException e) {
62     } // assume there are no tasks
63     return new IMarker[0];
64   }
65
66   //            public static void finishedBuilding(IResourceChangeEvent event) {
67   //                    BuildNotifier.resetProblemCounters();
68   //            }
69
70   public static void removeProblemsFor(IResource resource) {
71     try {
72       if (resource != null && resource.exists())
73         resource.deleteMarkers(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER, false, IResource.DEPTH_INFINITE);
74     } catch (CoreException e) {
75     } // assume there were no problems
76   }
77
78   public static void removeTasksFor(IResource resource) {
79     try {
80       if (resource != null && resource.exists())
81         resource.deleteMarkers(IJavaModelMarker.TASK_MARKER, false, IResource.DEPTH_INFINITE);
82     } catch (CoreException e) {
83     } // assume there were no problems
84   }
85
86   public static void removeProblemsAndTasksFor(IResource resource) {
87     try {
88       if (resource != null && resource.exists()) {
89         resource.deleteMarkers(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER, false, IResource.DEPTH_INFINITE);
90         resource.deleteMarkers(IJavaModelMarker.TASK_MARKER, false, IResource.DEPTH_INFINITE);
91       }
92     } catch (CoreException e) {
93     } // assume there were no problems
94   }
95   public static State readState(IProject project, DataInputStream in) throws IOException {
96     return State.read(project, in);
97   }
98
99   public static void writeState(Object state, DataOutputStream out) throws IOException {
100     ((State) state).write(out);
101   }
102
103   /**
104    * Constructor
105    */
106   public PHPBuilder() {
107   }
108
109   /**
110    * 
111    */
112   protected IProject[] build(int kind, Map args, IProgressMonitor monitor) throws CoreException {
113     monitor.beginTask("Parsing files", TOTAL_WORK);
114     this.currentProject = getProject();
115     if (currentProject == null || !currentProject.isAccessible())
116       return new IProject[0];
117
118     if (kind == IncrementalProjectBuilder.FULL_BUILD) {
119       IResourceDelta delta = getDelta(getProject());
120
121       processFull(getProject(), monitor);
122
123     } else { // INCREMENTAL_BUILD or AUTO_BUILD
124
125       IResourceDelta delta = getDelta(getProject());
126       if (delta != null) {
127         delta.accept(new ParserVisitor(getProject(), monitor));
128       }
129
130     }
131     monitor.done();
132     return null;
133   }
134
135   /**
136    * Performs a <code>FULL_BUILD</code> by visiting all nodes in the resource
137    * tree under the specified project.  
138    * 
139    * @param iProject
140    */
141   public void processFull(final IProject iProject, final IProgressMonitor monitor) {
142     final IdentifierIndexManager indexManager = PHPeclipsePlugin.getDefault().getIndexManager(iProject);
143     // Create resource visitor logic
144     IResourceVisitor myVisitor = new IResourceVisitor() {
145       public boolean visit(IResource resource) throws CoreException {
146         if (resource.getType() == IResource.FILE) {
147           if (monitor.isCanceled()) {
148             throw new OperationCanceledException();
149           }
150           if ((resource.getFileExtension() != null) && PHPFileUtil.isPHPFile((IFile) resource)) {
151             monitor.worked(1);
152             monitor.subTask("Parsing: " + resource.getFullPath());
153             // check for parsing errors
154             PHPParserAction.parseFile((IFile) resource);
155             // update indexfile for the project:
156             JavaProject nature = (JavaProject) iProject.getNature(PHPeclipsePlugin.PHP_NATURE_ID);
157             indexManager.addFile((IFile) resource);
158           }
159         }
160
161         return true;
162       }
163     };
164
165     // Process the project using the visitor just created
166     try {
167
168       //      if (iProject.hasNature(PHPeclipsePlugin.PHP_NATURE_ID)) {
169       //        thePHPProject = new PHPProject();
170       //        thePHPProject.setProject(iProject);
171       //      }
172       indexManager.initialize();
173       iProject.accept(myVisitor);
174       indexManager.writeFile();
175     } catch (CoreException e) {
176       e.printStackTrace();
177     }
178
179   }
180
181   /** 
182    * Sets initialization data for this builder.
183    * <p>
184    * This method is part of the <code>IExecutableExtension</code>
185    * interface.
186    * </p>
187    * <p>
188    * Subclasses are free to extend this method to pick up 
189    * initialization parameters from the plug-in plug-in manifest 
190    * (<code>plugin.xml</code>) file,
191    * but should be sure to invoke this method on their superclass.
192    * <p>
193    * For example, the following method looks for a boolean-valued 
194    * parameter named "trace":
195    * <pre>
196    *     public void setInitializationData(IConfigurationElement cfig, 
197    *             String propertyName, Object data) 
198    *                    throws CoreException {
199    *         super.setInitializationData(cfig, propertyName, data);
200    *         if (data instanceof Hashtable) { 
201    *             Hashtable args = (Hashtable) data; 
202    *             String traceValue = (String) args.get("trace"); 
203    *             TRACING = (traceValue!=null && traceValue.equals("true"));
204    *         }
205    *     }
206    * </pre>
207    * </p>
208    */
209   public void setInitializationData(IConfigurationElement config, String propertyName, Object data) throws CoreException {
210     super.setInitializationData(config, propertyName, data);
211
212   }
213
214   /**
215    * Informs this builder that it is being started by the build management
216    * infrastructure.  By the time this method is run, the builder's project
217    * is available and <code>setInitializationData</code> has been called.
218    * The default implementation should be called by all overriding methods.
219    *
220    * @see #setInitializationData
221    */
222   protected void startupOnInitialize() {
223     //   traceMsg("Parse Builder Initialize - startupOnInitialize()");
224   }
225
226   /**
227   * Write trace statements.  
228   * System.out.println with prefix tagging used for simplicity.
229   */
230   //  private void traceMsg(String msg) {
231   //    if (PHPeclipsePlugin.DEBUG | traceEnabled)
232   //      System.out.println(
233   //        buildMode
234   //          + "<"
235   //          + getProject()
236   //          + "> "
237   //          + "\t\t\t"
238   //          + buildMark
239   //          + msg);
240   //  }
241
242 }